将ObservableCollection绑定到MVVM中的DataGrid
我有一个DataGrid,我绑定到我的视图模型中的ObservableCollection,我需要能够在DataGrid排序时对集合进行排序,以便我可以在其他地方使用此排序顺序。 我目前正在使用ObvservableCollection上的包装器来支持排序。 对DataGrid进行排序时,它只对显示的数据进行排序,而不对集合中的基础数据进行排序。 数据由一个整数列和一个字符串列组成,需要在两者上支持升序和降序排序。 我还希望保持与标准DataGrid排序相同的用法,您可以在其中单击列标题并在升序和降序排序之间切换。 我对WPF比较陌生,所以我不知道数据和命令绑定的所有细节,但我认为有一种方法可以实现我想做的事情。 这是一个示例xaml来说明我的视图设置。
源数据的类型如下:
public class myType { public int firstValue { get; set; } public string secondValue { get; set; } // some functions and variables... }
现在,就像我上面所说的,我需要按照排序顺序访问集合中的项目,但它不需要特别是ObservableCollection。 只要我可以在我访问它们时按当前顺序迭代集合中的项目,一切都很好。 我想的可能是ListCollectionView或其他东西。 当新项目添加到集合中时,我也不希望集合重新排序。 任何新项目都应该像通常会发生的那样添加到集合的末尾。
有任何想法吗?
DataGrid
使用基于DataSource的底层ICollectionView
,因此如果您直接绑定ICollectionView
您可以访问已排序的值,因为DataGrid
将在排序时直接更改ICollectionView
。
小例子:
码:
public partial class MainWindow : Window { public MainWindow() { // dummy data source / Your ObservableCollection var yourObservableCollection = Enumerable.Range(0, 30) .Select(i => new MyType { FirstValue = i, SecondValue = i.ToString() }); // Create CollectionView based on the data you want to show MySource = CollectionViewSource.GetDefaultView(yourObservableCollection); InitializeComponent(); } public ICollectionView MySource { get; set; } private void Button_Click_1(object sender, RoutedEventArgs e) { foreach (var item in MySource.OfType()) { Console.WriteLine("MyType - First: {0}, Second: {1}", item.FirstValue, item.SecondValue); } } } public class MyType { public int FirstValue { get; set; } public string SecondValue { get; set; } }
XAML:
我知道这是一个老问题,但是当我遇到类似的问题时,我很难找到答案,我想按照屏幕上显示的顺序打印/导出数据。 虽然@ sa_ddam213的答案是正确的,但需要进行一些调整以适应MVVM模式,所以希望这对其他人有用。 为了实现这一点,首先向视图模型添加ICollectionView(我相信这与UI使用的数据结构相同):
private ObservableCollection tableData = new ObservableCollection (); // The DataGridknow was originally bound to this private ICollectionView tableDataWrapper;
然后为ICollectionView添加一个新的Getter / Setter:
public ICollectionView TableDataWrapper { get { return this.tableDataWrapper; } set { this.tableDataWrapper = value; OnPropertyChanged("tableDataWrapper"); } }
在原始的TableData Setter中,每次设置表数据时都添加一行来设置包装器:
public ObservableCollection TableData { get { return this.tableData; } set { this.tableData = value; this.TableDataWrapper = CollectionViewSource.GetDefaultView(tableData); // Add this OnPropertyChanged("tableData"); } }
现在更新DataGrid的Bindings,使其绑定到TableDataWrapper
而不是TableData
Now以按排序顺序访问数据:
this.TableDataWrapper.Cast().ToList ()
或者如果你想要它作为ObservableCollection:
new ObservableCollection( this.TableDataWrapper.Cast().ToList () )
您可以使用ICollectionView对现有集合进行排序。 它位于System.ComponentModel下
代码是这样的
var collectionView = CollectionViewSource.GetDefaultView(ObservableCollection_Name); collectionView.SortDescriptions.Add(new SortDescription("Your Property", ListSortDirection.Descending));
在GridView或ListView中,您可以绑定现有的ObservableCollection。 无需改变。
- 从PropertyGrid显示详细的文件夹浏览器
- 使用Entity Framework执行简单查询时出现严重的性能问题
- HowTo:使用MvcContrib.Pagination而不使用MvcContrib.Grid View
- 按钮的键盘快捷键
- WPF TabControl,用C#代码更改TabItem的背景颜色
- 适用于Silverlight 4 + WCF数据服务的IAsyncRepository或IObservableRepository
- Google使用服务帐户协调OAuth2
- 使用字符串参数调用web api
- 使用有效的Double向DateTime添加秒可导致ArgumentOutOfRangeException