我正在开发 WPF MVVM 应用程序并遇到问题。我对 WPF 本身很熟悉,但是我很少使用 MVVM,而且我怀疑我正在做一些 MVVM 不支持的事情,但是我不知道如何完成我想做的事情。
在应用程序中,我有一个名为 Agenda 的用户控件。它包含几个控件,包括一个文本框、一个添加新议程项目的按钮和一个带有自定义模板的列表框。该模板包括一个扩展器,其中标题是议程项目标题、用于重新排序项目的向上/向下箭头以及用于删除项目的按钮。扩展器内容包含一个工具栏和一个富文本框。在议程 UC 我有一个名为的依赖属性ItemsSource,它是一个IEnumerable<AgendaItem>.
现在,我有一个名为 Appointment 的视图、它的关联 VM (AppointmentViewModel) 和它的模型 (AppointmentModel)。在模型中,有一个名为 AgendaItems 的字段,它是一个ObservableCollection<AgendaItem>. 议程 UC 在约会视图中使用,并且 UCItemsSource绑定到Model.AgendaItems(可观察的集合)。
我遇到的问题是当我尝试处理按钮以重新排序 UC 中的议程项目时。例如,对于将议程项目上移到列表中的按钮,这是 UC 中的代码:
var tb = sender as Button;
var tag = tb.Tag as AgendaItem;
var lst = ItemsSource.ToList();
var index = lst.IndexOf(tag);
if(index > 0)
{
lst.RemoveAt(index);
lst.Insert(index - 1, tag);
ItemsSource = lst;
}
向上箭头的标记绑定到列表中的特定议程项目,因此我知道正在移动哪个项目。问题出现在我更新ItemsSource属性之后ItemsSource = lst。该行执行后,AgendaItemsVM 中的 ObservableCollection 为空。绑定模式设置为TwoWay。
由于约会 UC 在应用程序的各个窗口中使用,因此对我来说,议程项目的重新排序应该由我的 UC 处理,而不是在每个使用 UC 的窗口中复制代码。但是更新ItemsSourceUC 中的属性会导致 VM 中的集合为空。
作为参考,ItemsSourceUC中的属性定义为:
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable<AgendaItem>), typeof(Agenda), new PropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged)));
有常规的 .NET 属性:
public IEnumerable<AgendaItem> ItemsSource
{
get => (IEnumerable<AgendaItem>)GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
OnItemsSourceChanged方法是:
private static void OnItemsSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is Agenda control)
{
if (e.OldValue is INotifyCollectionChanged oldValueINotifyCollectionChanged)
{
oldValueINotifyCollectionChanged.CollectionChanged -= control.ItemsSource_CollectionChanged;
}
if (e.NewValue is INotifyCollectionChanged newValueINotifyCollectionChanged)
{
newValueINotifyCollectionChanged.CollectionChanged += control.ItemsSource_CollectionChanged;
}
}
}
任何关于如何ItemsSource在不破坏 VM 的情况下在 UC 中重新排序集合的帮助/指导将不胜感激。先感谢您。