对 ListBox 中的 ObservableCollection<Class> 数据进行排序
Sorting ObservableCollection<Class> data in ListBox
我的程序有两个列表框。他们通过 Add
和 Remove
按钮互相交换物品。在添加和删除过程中,我想对项目进行排序(按ID),使用OrderBy
,但我不知道如何使用这个查询结果。在我的案例中如何使用 OrderBy
?
好像OrderBy
可以用,就是不知道放哪里:
IEnumerable<GraphViewModel> query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
??? = query_orderBy_ID;
... 好吧,那我把右手边拿回来放回原来的集合中:
RightListBoxItems = (ObservableCollection<GraphViewModel>)RightListBoxItems.OrderBy(value => value.ID).ToList();
error CS0030: Cannot convert type
'System.Collections.Generic.List'
to
'System.Collections.ObjectModel.ObservableCollection'
我以为转换会解决这个问题,但它不起作用。
这是我的代码:
MainWindow.xaml.cs
已编辑: 在 Add_Button_Click()
中添加了一个 query_orderBy_ID
循环并使其更简单,抱歉:
using Sorting_List_with_OrderBy.ViewModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
namespace Sorting_List_with_OrderBy
{
public partial class MainWindow : Window
{
public ObservableCollection<GraphViewModel> LeftListBoxItems { get; set; }
= new ObservableCollection<GraphViewModel>();
public ObservableCollection<GraphViewModel> RightListBoxItems { get; set; }
= new ObservableCollection<GraphViewModel>();
ObservableCollection<string> TestItems = new ObservableCollection<string>();
IEnumerable<GraphViewModel> query_orderBy_ID;
public MainWindow()
{
InitializeComponent();
DataContext = this;
TestItems.Add("T0");
TestItems.Add("T1");
TestItems.Add("T2");
foreach (var test in TestItems.Select((k, i) => new { kvp = k, index = i }))
{
LeftListBoxItems.Add(new GraphViewModel(test.index, test.kvp));
}
}
private void Add_Button_Click(object sender, RoutedEventArgs e)
{
foreach (var graphViewModel in LeftListBox.SelectedItems.Cast<GraphViewModel>().ToList())
{
LeftListBoxItems.Remove(graphViewModel);
// 1st Attempt: I don't know where to put this result to ...
query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
// 2nd Attempt: This substitution fails ...
//RightListBoxItems = (ObservableCollection<GraphViewModel>)RightListBoxItems.OrderBy(value => value.ID).ToList();
RightListBoxItems.Add(graphViewModel);
}
query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
foreach (GraphViewModel orderBy_ID in query_orderBy_ID)
{
MessageBox.Show(orderBy_ID.ID + ": " + orderBy_ID.TestName);
}
}
private void Remove_Button_Click(object sender, RoutedEventArgs e)
{
foreach (var graphViewModel in RightListBox.SelectedItems.Cast<GraphViewModel>().ToList())
{
RightListBoxItems.Remove(graphViewModel);
LeftListBoxItems.Add(graphViewModel);
}
}
}
}
MainWindow.xaml
<Window x:Class="Sorting_List_with_OrderBy.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Sorting_List_with_OrderBy"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="600">
<Grid>
<ListBox Margin="15,158,0,69.8" x:Name="LeftListBox" HorizontalAlignment="Left" Width="184" Background="AntiqueWhite"
SelectionMode="Extended" ItemsSource="{Binding LeftListBoxItems}" DisplayMemberPath="TestName"/>
<Button x:Name="Add_Button" Height="26" Margin="232,196,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80"
Click="Add_Button_Click" Content="Add >>"/>
<Button x:Name="Remove_Button" Margin="230,267,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="82"
Click="Remove_Button_Click" Height="26" Content="<< Remove"/>
<ListBox Margin="343,158,0,71.8" x:Name="RightListBox" HorizontalAlignment="Left" Width="200" Background="AntiqueWhite"
SelectionMode="Extended" ItemsSource="{Binding RightListBoxItems}" DisplayMemberPath="TestName"/>
</Grid>
</Window>
ViewModel/GraphViewModel.cs
namespace Sorting_List_with_OrderBy.ViewModel
{
public class GraphViewModel
{
public int ID { get; }
public string TestName { get; }
public GraphViewModel(int id, string testName) => (ID, TestName) = (id, testName);
}
}
这个问题的主要目的是对我的 ListBox 进行排序,因此 ListBox 项目应该按正确的顺序排序 [T0
、T1
、T2
]。相信如果上述问题解决了,他们会得到解决的。
任何建议都会有所帮助。谢谢。
OrderBy
将 return 一个 IOrderedEnumerable<T>
根据排序键排序。原始集合保持其原始状态。因此,您需要用排序后的结果集合覆盖原始集合:
this.LeftListBoxItems = new ObservableCollection<GraphViewModel>(this.LeftListBoxItems.OrderBy(value => value.ID))
要让 ObservableCollection
在 adding/removing 项时自动排序,您可以通过将 SortDescription
添加到 ICollectionView
来配置一次(例如,从构造函数) :
CollectionViewSource.GetDefaultView(this.LeftListBoxItems)
.SortDescriptions
.Add(new SortDescription(nameof(GraphViewModel.ID), ListSortDirection.Ascending));
备注
WPF 绑定到集合的 ICollectionView
而不是直接绑定到集合。在 ICollectionView
上设置 SortDescription
只会对 ICollectionView
进行排序。这意味着 UI 看起来已排序,而基础集合仍未排序(或按不同规则排序)。
我的程序有两个列表框。他们通过 Add
和 Remove
按钮互相交换物品。在添加和删除过程中,我想对项目进行排序(按ID),使用OrderBy
,但我不知道如何使用这个查询结果。在我的案例中如何使用 OrderBy
?
好像OrderBy
可以用,就是不知道放哪里:
IEnumerable<GraphViewModel> query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
??? = query_orderBy_ID;
... 好吧,那我把右手边拿回来放回原来的集合中:
RightListBoxItems = (ObservableCollection<GraphViewModel>)RightListBoxItems.OrderBy(value => value.ID).ToList();
error CS0030: Cannot convert type 'System.Collections.Generic.List' to 'System.Collections.ObjectModel.ObservableCollection'
我以为转换会解决这个问题,但它不起作用。
这是我的代码:
MainWindow.xaml.cs
已编辑: 在 Add_Button_Click()
中添加了一个 query_orderBy_ID
循环并使其更简单,抱歉:
using Sorting_List_with_OrderBy.ViewModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
namespace Sorting_List_with_OrderBy
{
public partial class MainWindow : Window
{
public ObservableCollection<GraphViewModel> LeftListBoxItems { get; set; }
= new ObservableCollection<GraphViewModel>();
public ObservableCollection<GraphViewModel> RightListBoxItems { get; set; }
= new ObservableCollection<GraphViewModel>();
ObservableCollection<string> TestItems = new ObservableCollection<string>();
IEnumerable<GraphViewModel> query_orderBy_ID;
public MainWindow()
{
InitializeComponent();
DataContext = this;
TestItems.Add("T0");
TestItems.Add("T1");
TestItems.Add("T2");
foreach (var test in TestItems.Select((k, i) => new { kvp = k, index = i }))
{
LeftListBoxItems.Add(new GraphViewModel(test.index, test.kvp));
}
}
private void Add_Button_Click(object sender, RoutedEventArgs e)
{
foreach (var graphViewModel in LeftListBox.SelectedItems.Cast<GraphViewModel>().ToList())
{
LeftListBoxItems.Remove(graphViewModel);
// 1st Attempt: I don't know where to put this result to ...
query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
// 2nd Attempt: This substitution fails ...
//RightListBoxItems = (ObservableCollection<GraphViewModel>)RightListBoxItems.OrderBy(value => value.ID).ToList();
RightListBoxItems.Add(graphViewModel);
}
query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
foreach (GraphViewModel orderBy_ID in query_orderBy_ID)
{
MessageBox.Show(orderBy_ID.ID + ": " + orderBy_ID.TestName);
}
}
private void Remove_Button_Click(object sender, RoutedEventArgs e)
{
foreach (var graphViewModel in RightListBox.SelectedItems.Cast<GraphViewModel>().ToList())
{
RightListBoxItems.Remove(graphViewModel);
LeftListBoxItems.Add(graphViewModel);
}
}
}
}
MainWindow.xaml
<Window x:Class="Sorting_List_with_OrderBy.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Sorting_List_with_OrderBy"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="600">
<Grid>
<ListBox Margin="15,158,0,69.8" x:Name="LeftListBox" HorizontalAlignment="Left" Width="184" Background="AntiqueWhite"
SelectionMode="Extended" ItemsSource="{Binding LeftListBoxItems}" DisplayMemberPath="TestName"/>
<Button x:Name="Add_Button" Height="26" Margin="232,196,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80"
Click="Add_Button_Click" Content="Add >>"/>
<Button x:Name="Remove_Button" Margin="230,267,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="82"
Click="Remove_Button_Click" Height="26" Content="<< Remove"/>
<ListBox Margin="343,158,0,71.8" x:Name="RightListBox" HorizontalAlignment="Left" Width="200" Background="AntiqueWhite"
SelectionMode="Extended" ItemsSource="{Binding RightListBoxItems}" DisplayMemberPath="TestName"/>
</Grid>
</Window>
ViewModel/GraphViewModel.cs
namespace Sorting_List_with_OrderBy.ViewModel
{
public class GraphViewModel
{
public int ID { get; }
public string TestName { get; }
public GraphViewModel(int id, string testName) => (ID, TestName) = (id, testName);
}
}
这个问题的主要目的是对我的 ListBox 进行排序,因此 ListBox 项目应该按正确的顺序排序 [T0
、T1
、T2
]。相信如果上述问题解决了,他们会得到解决的。
任何建议都会有所帮助。谢谢。
OrderBy
将 return 一个 IOrderedEnumerable<T>
根据排序键排序。原始集合保持其原始状态。因此,您需要用排序后的结果集合覆盖原始集合:
this.LeftListBoxItems = new ObservableCollection<GraphViewModel>(this.LeftListBoxItems.OrderBy(value => value.ID))
要让 ObservableCollection
在 adding/removing 项时自动排序,您可以通过将 SortDescription
添加到 ICollectionView
来配置一次(例如,从构造函数) :
CollectionViewSource.GetDefaultView(this.LeftListBoxItems)
.SortDescriptions
.Add(new SortDescription(nameof(GraphViewModel.ID), ListSortDirection.Ascending));
备注
WPF 绑定到集合的 ICollectionView
而不是直接绑定到集合。在 ICollectionView
上设置 SortDescription
只会对 ICollectionView
进行排序。这意味着 UI 看起来已排序,而基础集合仍未排序(或按不同规则排序)。