ICollectionView ui is not updated



我有与ICollectionView关联的ObserveCollection(实体(在我尝试删除条目之前,一切都很好。点击"删除"按钮后,界面不会更新。如果我设置ObserveCollection,一切都可以正常

private ICollectionView _taskview;
public ICollectionView TasksView 
{
get { return _taskview; }
set
{
_taskview = value;
OnPropertyChanged("TaskView");
}
}
public ICommand DeleteTask
{
get
{
return new DelegateCommand(() =>
{
_context.Task.Attach(SelectTask);
_context.Task.Remove(SelectTask);
_context.SaveChanges();
Tasks = new ObservableCollection<TaskModel>(_context.Task);
TasksView = CollectionViewSource.GetDefaultView(Tasks);
});
}
}
public HomeViewModel(Window window)
{
this.window = window;
Tasks = new ObservableCollection<TaskModel>(_context.Task);
TasksView = CollectionViewSource.GetDefaultView(Tasks);
}

<ListBox Grid.Row="1" Grid.RowSpan="2" Grid.Column="0"
SelectionMode="Extended"
ItemsSource="{Binding TasksView}"
SelectedItem="{Binding SelectTask}">
</ListBox>

每次删除后不要创建新集合。这将对性能产生负面影响。这就是您使用ObservableCollection的原因。通过这种方式,绑定目标(例如ListBox(能够仅更新更改的项,而不是重新创建/呈现完整的视图。

在这种情况下,将数据源公开为ICollectionsView也是没有意义的。而是直接与CCD_ 4结合。

ICollectionsView的源集合像ObservableCollection<T>那样实现INotifyCollectionChanged时,ICollectionView将在源更改时自动更新
在这种情况下,操纵INotifyCollectionChanged集合就足够了。

ICollectionsView的源集合不像List<T>那样实现INotifyCollectionChanged时,ICollectionView将不会在源更改时自动更新
在这种情况下,必须显式调用ICollectionView.Refresh以强制更新ICollectionView

请注意,您应该永远不要引用视图模型中的任何视图组件-没有例外。这消除了MVVM的所有优点。当然,这是从来没有必要的。如果视图模型需要对视图组件的引用,则表明您的代码或类设计错误。要遵循此基本MVVM设计规则,必须HomeViewModel中删除对Window的引用
您可以通过公开视图模型上的属性来触发视图行为,该属性是视图中数据触发器的输入。模式-WPF应用程序与模型视图视图模型设计模式,模型视图视图模式。

第一个解决方案(推荐(

您应该直接绑定到Tasks集合
您需要操作集合的视图的时刻,例如,应用过滤器,使用CollectionViewSource.GetDefaultView(Tasks)检索视图。但不要拘泥于此。

<ListBox ItemsSource="{Binding Tasks}" />
public HomeViewModel()
{
Tasks = new ObservableCollection<TaskModel>(_context.Task);
Tasks.CollectionChanged += OnTasksChanged;
}
private void OnTasksChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
{
foreach (TaskModel task in e.NewItems)
{
_context.Task.Add(task);
_context.SaveChanges();
}
break;
}
case NotifyCollectionChangedAction.Remove:
{
foreach (TaskModel task in e.OldItems)
{
_context.Task.Attach(task);
_context.Task.Remove(task);
_context.SaveChanges();
}
break;
}
}
}
// Then simply manipulate the 'Tasks' collection
public ICommand DeleteTaskCommand => new DelegateCommand(() => Tasks.Remove(SelectTask));

第二个解决方案

如果您想绑定到ICollectionView,则不再需要额外的ObservableCollection(除非您想在每次添加/移动/删除/重置操作中维护两个集合和一个ICollectionView(。要更新集合的视图,请调用ICollectionView.Refresh

<ListBox ItemsSource="{Binding TasksView}" />
public HomeViewModel()
{
TasksView = CollectionViewSource.GetDefaultView(_context.Task);
}

// Then simply refresh the 'TasksView': 
public ICommand DeleteTask => DelegateCommand(
() =>
{
_context.Task.Attach(SelectTask);
_context.Task.Remove(SelectTask);
_context.SaveChanges();
// Update the view
TasksView.Refresh();
});

对CollectionViewSource的View属性调用Refresh((以刷新它。

您在上有一个拼写错误

public ICollectionView TasksView 
{
get { return _taskview; }
set
{
_taskview = value;
OnPropertyChanged("TaskView");
}
}

OnPropertyChanged("任务视图"(应该是OnPropertyChanged("TasksView");

最新更新