数据刷新后如何保持当前的ICollection类型?

时间:2013-06-24 09:59:38

标签: c# wpf data-binding mvvm icollectionview

我的应用程序客户端/服务器出了问题。我使用MVVM模式。在我看来,我的DataGrid与我的ViewModel中的ICollection绑定了这些代码行:

public ICollectionView Customers
    {
        get
        {
            return _customers;
        }
        set
        {
            _customers= value;
            RaisePropertyChanged("Customers");
        }
    }

_customers = CollectionViewSource.GetDefaultView(Manager.Instance.Customers());
_customers .SortDescriptions.Add(new SortDescription("CreationDate", ListSortDirection.Descending));

一开始,这两行都运行良好:我的DataGrid有我的客户列表,排序正常。

但是当服务器更新我的客户列表时,我想更新我的收藏集,以及我的DataGrid。 所以,我收到了我的新客户列表的通知。当我收到此通知时,我会用以下行更新我的收藏:

 Customers = CollectionViewSource.GetDefaultView(e.CustomersInfo);
_customers.SortDescriptions.Clear();
_customers .SortDescriptions.Add(new SortDescription("CreationDate", ListSortDirection.Descending));
Customers.Refresh();

在这里,我的DataGrid很好地刷新了良好的数据,但排序不刷新因为,开始时,我的客户列表按CreationDate排序,但刷新后,我的列表已排序by CustomersName。

在这里,我的XAML代码:

<DataGrid AutoGenerateColumns="false" ItemsSource="{Binding Customers, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True" Name="dtgEventInfo" SelectedItem="{Binding SelectedCustomers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemContainerStyle="{StaticResource ItemContStyle}" IsEnabled="True" IsReadOnly="True" Margin="0,0,330,0" GridLinesVisibility="None" SelectionMode="Single">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Name, Mode=TwoWay}" Header="Name" MinWidth="40" Width="Auto"/>
                    <DataGridTextColumn Binding="{Binding CreationDate, Mode=TwoWay}" Header="Date" MinWidth="50" Width="Auto"/>
                </DataGrid.Columns>
</DataGrid>

你有什么想法可以帮助我吗?经过一些研究,我发现任何解决方案......

5 个答案:

答案 0 :(得分:0)

我认为您应该将RaisePropertyChanged("Events");替换为RaisePropertyChanged("Customers");

答案 1 :(得分:0)

当需要你想要的行为时,我会做下面的事情:

  • 我创建一个我的类型ONCE的ObservableCollection,例如。 _mysource
  • 我创建一个ICollectionView ONCE例如。 _myview
  • 我使用清除/添加/删除来更新_mysource
  • 在_myview.Refresh()
  • 上应用排序/分组/过滤

所以这对你有用

 this._mysource.Clear();
 this._mysource.AddRange(e.CustomersInfo);
 _myview.Refresh();

答案 2 :(得分:0)

你可以尝试两件事

  1. 在ViewModel类中实现INotifyPropertyChanged接口,可以在需要时更新UI。请参阅http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

  2. 使用ObservableCollection而不是CollectionView,它已经实现了INotifyPropertyChanged接口,并在需要时更新UI。通过实现IComparer接口也可以进行排序操作。请参阅链接http://msdn.microsoft.com/en-us/library/ms668604.aspx

  3. 如果有用,请标记答案

答案 3 :(得分:0)

我猜你的更新方法是在主线程的不同线程中运行的。你可以试试这个:

if (Application.Current.Dispatcher.CheckAccess())
{
    UpdateCollectionView(e.CustomersInfo);
}
else
{
    Application.Current.Dispatcher.Invoke(new Action(() => UpdateCollectionView(e.CustomersInfo)));
}
private void UpdateCollectionView(IEnumerable<Customer> customers)
{
    Customers = CollectionViewSource.GetDefaultView(customers);
    Customers.SortDescriptions.Clear();
    Customers.SortDescriptions.Add(new SortDescription("CreationDate", ListSortDirection.Descending));
    Customers.Refresh();
}

答案 4 :(得分:0)

在Visual Studio中进行了一些搜索和大量调试模式之后,我想我已经找到了问题所在。在我的经理Manager.cs中,当我收到通知时,我这样做了:

 ObservableCollection<CustomerInfo> collection = new ObservableCollection<CustomerInfo>(e.CustomersInfoList); 
CustomerListViewModel.Instance.Customers = collection; 

所以,这个新的实例化可能会导致我的问题,因为,在同一个集合中,我实现了一些过滤器,并且,在过滤方法之后排序是正常的!

你现在有什么想法吗?