在DataGridView中对选定的行进行排序

我在Winforms应用程序中有一个DataGridView。 我想在其中选择一组行,并按列(Timestamp)对这些行进行排序…

其余的行应该保持原来的状态。可以使用DGV的sort属性来完成

谢谢

可以使用DGV的sort属性完成此操作

没有

DataGridView上的Sort方法用于更简单的排序。 例如Ascending或Descending排序, SortOrder属性也只是用于“简单”排序。

这种行为可以实施吗? 当然。

我认为最简单的方法是:

  • 存储第一个选定项目的索引
  • DataGridView取出要排序的项目
  • 使用LINQ对列表进行排序
  • 附加两个列表,并将排序列表添加到第一步中存储的索引处。

但是,如果您选择彼此不跟随的项目,则需要考虑如何处理,例如,如果选择索引{ 1, 3, 6, 9 } 1,3,6,9 { 1, 3, 6, 9 }您可能希望将其附加到索引1

编辑

好的,所以我稍微玩了一下,然后提出了一种方法,你可以实现这一点。 它不是很优化,但你会明白我的意思。

首先,这是我使用的SortSelectedIndices方法:

 static IEnumerable SortSelectedIndices( IEnumerable values, IEnumerable selectedIndices, Func, IEnumerable> sort) { var selectedValues = new List(); for (var i = 0; i < selectedIndices.Count(); i++) selectedValues.Add(values.ElementAt(selectedIndices.ElementAt(i))); var sortedList = sort(selectedValues); var finalList = new List(); var startPositionFound = false; for(var i = 0; i < values.Count(); i++) { if (selectedIndices.Contains(i)) { if (startPositionFound) continue; startPositionFound = true; finalList.AddRange(sortedList); } else finalList.Add(values.ElementAt(i)); } return finalList; } 

然后我称之为:

 static void Main(string[] args) { var unsorted = new[] {3, 5, 6, 1, 2, 87, 432, 23, 46, 98, 44}; var selected = new[] {1, 4, 7}; Print(unsorted); var sort = new Func, IEnumerable>( (x) => x.OrderBy(y => y).ToList()); var sorted = SortSelectedIndices(unsorted, selected, sort); Print(sorted); } 

这打印出以下内容:

 { 3,5,6,1,2,87,432,23,46,98,44 } { 3,2,5,23,6,1,87,432,46,98,44 } 

我只是在这里使用一个简单的方法将其打印到控制台:

 static void Print(IEnumerable values) { Console.Write("{ "); Console.Write(string.Join(",", values)); Console.WriteLine(" }"); } 

所以你可以做的就是有一个“排序”按钮,当你按下它时你调用SortSelectedIndices然后在你完成时重新绑定列表。 请记住,我没有对此代码进行分析或重构,它可能没有您想要的那么快,我只是想让您了解如何实现该解决方案。

基于Filips对问题的定义,以及他作为正确答案的例子,我的一般性(没有generics,没有Func)解决方案将是这样的:

 Public Function SortSelectedIndices(unsortedList As IEnumerable(Of Integer), selectedIndices As IEnumerable(Of Integer)) As IEnumerable(Of Integer) If Not selectedIndices.Any() Then Return unsortedList End If Dim extractedValues = From s In selectedIndices Select unsortedList(s) Dim sortedExtractedValues = From e In extractedValues Order By e Dim listWithoutExtractedValues = unsortedList.Except(extractedValues) Dim resultList = New List(Of Integer)(listWithoutExtractedValues) Dim firstSelectedIndex = Aggregate s In selectedIndices Order By s Into First() resultList.InsertRange(firstSelectedIndex, sortedExtractedValues) Return resultList End Function 

编辑:菲利普刚刚指出问题标记为“C#”。 但是在文中没有提到这一点,所以我认为它并不重要。 我还假设任何熟悉.NET的读者都可以将“昏暗”翻译成“var”和喜欢的东西。 😛

当然,DataGridView无法做到这一点。 因此,最好的解决方案是创建一个新的集合(List),用GridView中的选定行填充它,最后使用它的Sort方法来排序这些行。 要按特定列对数据进行排序,您可以编写自定义IComparer类并将其传递给Sort方法或使用Linq:

var orderedList = someList.OrderBy(obj => obj.TimeStampField);