[英]Nested view model in WPF
Still trying to learn MVVM and WPF here. 仍然尝试在此处学习MVVM和WPF。
I'm trying to create a complex view model EditArticleViewModel
. 我正在尝试创建一个复杂的视图模型
EditArticleViewModel
。 It has some code that is repeated for similar controls and so I've moved the repeating code into another class. 它有一些针对相似控件重复的代码,因此我将重复的代码移到了另一个类中。 Then, I've added several instances of that other class into
EditArticleViewModel
. 然后,我将另一个类的几个实例添加到
EditArticleViewModel
。
I will set an instance of EditArticleViewModel
as my window's DataContext
. 我将把
EditArticleViewModel
的实例设置为窗口的DataContext
。 And I will bind to things like Categories.Items
and Subcategories.SelectedItem
. 我将绑定到
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
}
As you can see, my EditArticleViewModel
class implements INotifyPropertyChanged
so that I can notify the visual elements when something has changed. 如您所见,我的
EditArticleViewModel
类实现了INotifyPropertyChanged
以便在发生更改时可以通知可视元素。
My question is about how I notify visual elements about changes within CategoryView
and SubcategoryView
. 我的问题是关于如何通知视觉元素有关
CategoryView
和SubcategoryView
更改的信息。 Is there a way to notify the window about changes within these classes directly? 有没有一种方法可以直接向窗口通知这些类中的更改? Or must I raise an event from each class and have
EditArticleViewModel
handle that event in order to send the appropriate notification? 还是我必须从每个类中引发一个事件并让
EditArticleViewModel
处理该事件才能发送适当的通知?
Any tips appreciated. 任何提示表示赞赏。
There should only be one ViewModel per View, with an extend that primary ViewModel can contain other "ViewModels". 每个视图只能有一个ViewModel,并且扩展方式是主ViewModel可以包含其他“ ViewModel”。
So when you set DataContext
to your primary ViewModel all the content of it will be have a subscription to NotifyPropertyChanged
event, thus implementing INotifyPropertyChanged
interface in other derived ViewModel will be notified. 因此,当您将
DataContext
设置为主ViewModel时,其所有内容将具有对NotifyPropertyChanged
事件的订阅,因此将通知在其他派生的ViewModel中实现INotifyPropertyChanged
接口。
I would suggest implementing a base class with INotifyPropertyChanged
interface
which you could derive from in your other ViewModels. 我建议使用
INotifyPropertyChanged
interface
实现基类,您可以从其他ViewModel中派生该interface
。
By having this alteration you should solve the problem you are having: 通过进行此更改,您应该解决您遇到的问题:
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();
}
Regarding ObservableCollection
. 关于
ObservableCollection
。 It will notify view to change only when you add/remove items but it does not notify when content is changed. 仅当您添加/删除项目时,它才会通知视图更改,但是当内容更改时,它不会通知。 To update view on item content change you should have something like that:
要更新有关项目内容更改的视图,您应该具有以下内容:
public class GridRowItemViewModel : ObservableViewModelBase // From previous example.
{
private string _sampleProp;
public string SampleProp
{
get
{
return _sampleProp;
}
set
{
_sampleProp = value;
OnPropertyChanged();
}
}
}
And thus your Main ViewModel should look something like this: 因此,您的Main ViewModel应该看起来像这样:
public class MainViewModel : ObservableViewModelBase // This is your DataContext.
{
public ObservableCollection<GridRowItemViewModel> GridCollection { get; set; }
}
EDIT: You cannot bind to fields, WPF does not resolve fields. 编辑:您不能绑定到字段,WPF不能解析字段。 It can only handle properties.
它只能处理属性。 So by creating plain fields of child ViewModels you are getting no where.
因此,通过创建子ViewModel的纯字段,您将无处可寻。 Change these into properties and you will be able to access its content in the View by the property name.
将它们更改为属性,您将可以通过属性名称在视图中访问其内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.