仍在尝试学习MVVM和WPF。
我正在尝试创建复杂的视图模型EditArticleViewModel
。它有一些代码可以重复用于类似的控件,因此我将重复的代码移动到另一个类中。然后,我已将其他类的几个实例添加到EditArticleViewModel
。
我会将EditArticleViewModel
的实例设置为我的窗口DataContext
。我会绑定Categories.Items
和Subcategories.SelectedItem
之类的内容。
public class CategoryView
{
public ObservableCollection<object> Items { /* */ }
public object SelectedItem { /* ... */ }
}
public class SubcategoryView
{
public ObservableCollection<object> Items { /* */ }
public object SelectedItem { /* ... */ }
}
public class EditArticleViewModel : INotifyPropertyChanged
{
public CategoryView Categories { get; private set; }
public SubcategoryView Subcategories { get; private set; }
public EditArticleViewModel()
{
Categories = new CategoryView();
SubcategoryView Subcategories new SubcategoryView();
}
// Additional properties and methods here
}
正如您所看到的,我的EditArticleViewModel
类实现了INotifyPropertyChanged
,以便在出现更改时通知可视元素。
我的问题是如何通知视觉元素CategoryView
和SubcategoryView
内的变化。有没有办法直接通知窗口有关这些类中的更改?或者我是否必须从每个班级中提出一个事件并让EditArticleViewModel
处理该事件以发送相应的通知?
任何提示赞赏。
答案 0 :(得分:2)
每个View应该只有一个ViewModel,主要ViewModel可以包含其他“ViewModels”。
因此,当您将DataContext
设置为主要ViewModel 时,其所有内容将订阅NotifyPropertyChanged
事件,从而实现INotifyPropertyChanged
接口将通知其他派生的ViewModel。
我建议您使用INotifyPropertyChanged
interface
实现一个基类,您可以从其他ViewModel中获取该基类。
通过这种改动,你应该解决你遇到的问题:
public class ObservableViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string propName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
public class CategoryView : ObservableViewModelBase
{
public ObservableCollection<object> Items { /* */ }
public object SelectedItem { /* ... */ }
}
public class SubcategoryView : ObservableViewModelBase
{
public ObservableCollection<object> Items { /* */ }
public object SelectedItem { /* ... */ }
}
public class EditArticleView : ObservableViewModelBase
{
public CategoryView Categories { get; set; } = new CategoryView();
public SubcategoryView Subcategories { get; set; } = new SubcategoryView();
}
关于ObservableCollection
。它只会在您添加/删除项目时通知视图更改,但在更改内容时不通知视图。要更新项目内容更改的视图,您应该具有以下内容:
public class GridRowItemViewModel : ObservableViewModelBase // From previous example.
{
private string _sampleProp;
public string SampleProp
{
get
{
return _sampleProp;
}
set
{
_sampleProp = value;
OnPropertyChanged();
}
}
}
因此您的主ViewModel看起来应该是这样的:
public class MainViewModel : ObservableViewModelBase // This is your DataContext.
{
public ObservableCollection<GridRowItemViewModel> GridCollection { get; set; }
}
编辑:您无法绑定到字段,WPF无法解析字段。它只能处理属性。因此,通过创建子ViewModel的纯字段,您将无法在哪里获得。将这些更改为属性,您将能够通过属性名称在View中访问其内容。