2

我的应用程序客户端/服务器有问题。我使用 MVVM 模式。在我看来,我在 ViewModel 中使用以下代码行DataGrid绑定了 a :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 排序的,但刷新后,我的列表是按客户名称排序的。

在这里,我的 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>

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

4

5 回答 5

0

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

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

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

那么你现在有什么想法了吗?

于 2013-06-25T07:21:37.070 回答
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();
}
于 2013-06-24T13:10:17.827 回答
0

当需要您想要的行为时,我会执行以下操作:

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

所以这对你有用

 this._mysource.Clear();
 this._mysource.AddRange(e.CustomersInfo);
 _myview.Refresh();
于 2013-06-24T10:25:58.933 回答
0

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

于 2013-06-24T10:09:35.747 回答
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

如果有用请标记答案

于 2013-06-24T10:27:17.250 回答