如何在添加项目时更新datagrid排序(使用MVVM而不使用代码隐藏)

时间:2012-06-30 21:42:33

标签: wpf mvvm datagrid

我有一个数据网格,可以在最初加载时正确排序。但是当我添加项目时它不会更新。如何在添加新项目时更新网格并进行排序?

<!-- This works for the initial sort, but when members get added to the collection
     the sort doesn't get updated. That's because CollectionViewSource doesn't 
     implement INotifyPropertyChanged. -->
<UserControl.Resources>
    <CollectionViewSource x:Key="SortedApplications" Source="{Binding Applications}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="Name" Direction="Ascending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</UserControl.Resources>

一种选择是在视图模型中对集合进行排序。但是如果我在Foo中显示所有的条形图,那么我就必须将条形图分解为它自己的属性(在视图模型中),这样我才能对它们进行排序。

如果可能的话,我想在不使用视图的代码隐藏的情况下这样做,因为我试图不在那里放置代码。

1 个答案:

答案 0 :(得分:0)

默认情况下,DataGrid支持排序而无需指定SortDescription。事实上,我认为您遇到的问题是您的SortDescription会覆盖DataGrid的排序。我推荐两件事之一:

  1. 删除SortDescription并让DataGrid处理排序
  2. 将CollectionViewSource移动到ViewModel并向DataGrid添加一个Sorting处理程序,该处理程序调用ViewModel并管理SortDescriptions。
  3. 如果您打算自行管理SortDescriptions,请记得在添加新的SortDescriptions集合之前清除它,以便排序顺序正确。

    <强>更新

    如果在将新项目添加到绑定到的集合中时DataGrid未更新,则您的集合不会引发CollectionChanged事件。确保你绑定了实现INofityCollectionChanged的东西 - 比如ObservableCollection。

    <强>更新 这是一个按排序顺序插入项目的示例。您的代码有何不同?

    XAML:

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="MainWindow">
    <Window.Resources>
        <CollectionViewSource x:Key="SortedApplications" Source="{Binding Items}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Age" Direction="Ascending"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    
    <StackPanel>
        <Button Content="Add Item" Click="AddItem_"/>
        <DataGrid ItemsSource="{Binding Source={StaticResource SortedApplications}}"/>
    </StackPanel>       
    </Window>
    

    代码:

    public partial class MainWindow : Window
    {
        public ObservableCollection<Person> Items { get; set; }
    
        public MainWindow()
        {
            DataContext = this;
            Items = new ObservableCollection<Person>();
            Items.Add(new Person { Name = "Foo", Age = 1 });
            Items.Add(new Person { Name = "Bar", Age = 3 });
            Items.Add(new Person { Name = "Foo", Age = 31 });
            Items.Add(new Person { Name = "Bar", Age = 42 });
            InitializeComponent();
    
        }
    
        private void AddItem_(object sender, RoutedEventArgs e)
        {
            Items.Add(new Person { Name = "test", Age = DateTime.Now.Second});
        }
    }
    
    
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }