简体   繁体   English

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

[英]How to keep the current sort of a ICollection after data refresh?

I've a problem in my application Client/Server. 我的应用程序客户端/服务器中有问题。 I work with the MVVM pattern. 我使用MVVM模式。 In my view, I've a DataGrid which is bound with a ICollection in my ViewModel with these lines of code : 在我看来,我有一个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));

At the start, these two lines work fine : my DataGrid has my list of customers and the sort is ok. 开始时,这两行工作正常:我的DataGrid有我的客户列表,排序还可以。

But when the server update my list of customer, i would like to Update my collection and, so, my DataGrid . 但是,当服务器更新我的客户列表时,我想更新我的集合,也就是我的DataGrid So, I received a notification with my new List of customers. 因此,我收到了有关新客户列表的通知。 When I received this notification, I update my collection with these lines : 收到此通知后,我将使用以下内容更新我的收藏集:

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

Here, my DataGrid is well refresh with the good data, but the sort is not refresh beacause, at the beginning, my list of customers is sorted by the CreationDate, but after the refresh, my list is sorted by CustomersName. 在这里,我的DataGrid用良好的数据很好地刷新了,但是排序没有刷新,因为在开始时,我的客户列表是按CreationDate排序的,但是刷新后,我的列表是按CustomersName排序的。

Here, my XAML code : 在这里,我的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>

Do you have any ideas to help me please ? 您有什么想法可以帮助我吗? After some researches, I've bot found any solutions... 经过研究后,我发现了所有的解决方案...

I think you should just replace RaisePropertyChanged("Events"); 我认为您应该只替换RaisePropertyChanged("Events"); by RaisePropertyChanged("Customers"); 通过RaisePropertyChanged("Customers");

when need the behavior you want, i do the follwoing: 当需要您想要的行为时,我会进行以下操作:

  • i create an ObservableCollection of my type ONCE eg. 我创建一个我类型的ObservableCollection例如。 _mysource _mysource
  • i create a ICollectionView ONCE eg. 我创建一个ICollectionView ONCE例如。 _myview _我的观点
  • i use Clear/Add/Remove to update _mysource 我使用清除/添加/删除来更新_mysource
  • sorting/grouping/filtering are applied, on _myview.Refresh() 在_myview.Refresh()上应用了排序/分组/过滤

so this would work for you 所以这对你有用

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

You can try 2 things 你可以尝试两件事

  1. Implement INotifyPropertyChanged Interface in your ViewModel class which is cappable of updating UI when required. 在ViewModel类中实现INotifyPropertyChanged接口,可以在需要时更新UI。 Please see the http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx 请参阅http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

  2. Use ObservableCollection instead of CollectionView, which is already implemented INotifyPropertyChanged interface and updates the UI when required. 使用ObservableCollection而不是CollectionView(已实现INotifyPropertyChanged接口),并在需要时更新UI。 Sorting operation also possible by implementing IComparer Interface. 通过实现IComparer接口也可以进行排序操作。 Please see the link http://msdn.microsoft.com/en-us/library/ms668604.aspx 请参阅链接http://msdn.microsoft.com/en-us/library/ms668604.aspx

Please mark the answer if useful 如果有用,请标记答案

I guess your updating method is running in different thread from main thread. 我猜您的更新方法正在与主线程不同的线程中运行。 You can try this: 您可以尝试以下方法:

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();
}

After some searches and lots of debug mode in Visual Studio, I think I've found my problem. 经过在Visual Studio中的一些搜索和大量调试模式后,我认为我已经找到了问题。 In my manager Manager.cs , when I received my notification, I did this: 在我的经理Manager.cs ,收到通知时,执行了以下操作:

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

So, this new instantiation can probably cause my problem, because, on this same collection, I realize some filter, and, the sort is OK after the filter method! 因此,这种新的实例化可能会引起我的问​​题,因为在同一集合上,我实现了一些过滤器,并且在过滤器方法之后排序是可以的!

So do you have any ideas now? 那么,您现在有什么想法吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM