ObservableCollection 事件传播和 MVVM 中的正确使用
ObservableCollection event propagation and correct usage in MVVM
我正在进入 MVVM 并开始使用 Prism 框架,在我的示例应用程序中我有典型的导航。其中一页应该列出一些应用程序,我想知道实施方面的差异。为了简单起见,这里是迄今为止代码中的一些小片段:
应用模型
public class Application : BindableBase
{
private string _commandLine;
private string _name;
private string _smallIconSource;
public string CommandLine
{
get { return _commandLine; }
set { SetProperty(ref _commandLine, value); }
}
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
public string SmallIconSource
{
get { return _smallIconSource; }
set { SetProperty(ref _smallIconSource, value); }
}
}
ApplicationPage ViewModel
public class ApplicationPageViewModel : BindableBase
{
private ObservableCollection<Application> _applicationCollection;
public ApplicationPageViewModel()
{
// load some collection entries here
}
public ObservableCollection<Application> ApplicationCollection
{
get { return _applicationCollection; }
set
{
// if (_applicationCollection != null)
// _applicationCollection.CollectionChanged -= ApplicationCollectionChanged;
SetProperty(ref _applicationCollection, value);
// if (_applicationCollection != null)
// _applicationCollection.CollectionChanged += ApplicationCollectionChanged;
}
}
}
应用程序页面视图
<!-- ... -->
<ItemsControl ItemsSource="{Binding ApplicationCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- some kind of representation of applications -->
<Label Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- ... -->
在 Internet 上的一些代码示例中,尤其是在 SO 上的一些问题中,我看到有人问是否像我那样存储 ObservableCollection
的 ViewModels 而不是 Models - 我很好奇这一点您什么时候会选择其中一个版本而不是另一个版本?
此外,我想知道 Application
class 中的更改是否反映在 ApplicationPageViewModel
class 中,或者我是否必须挂接到 CollectionChanged
事件(正如我在 Brian Lagunas 的网络研讨会上看到的那样,我在其中看到了这种技术)。到目前为止,我只看到这个钩子进入 CollectionChanged
事件以调用 RaiseCanExecuteChanged
方法,如果手动 DelegateCommands
以防止在 [=21= 的以下实现时不必要的 bloat/calls ]s:
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
如果您的集合中的属性发生变化,我会使用 ViewModel。如果项目上的数据没有改变,那么使用 VM 或模型并没有真正的区别,这只是您喜欢的方式。
我个人喜欢将我的模型包装在 ViewModel 中,因为我可以轻松地添加组合属性以进行显示,而我不想直接在我的模型中使用这些属性。
如果您想在应用程序更改时对 ApplicationPageViewModel 执行某些操作,则必须
- 为应用程序使用 ViewModel
- 连接每个 Application ViewModel 的 INotifyPropertyChanged 事件
- 每次添加新的应用程序时,也将侦听器添加到此应用程序
如果您只想在添加或删除应用程序时执行一些操作,则不必使用 ViewModel,只需注册 ObservableCollection 的 CollectionChanged 事件
我正在进入 MVVM 并开始使用 Prism 框架,在我的示例应用程序中我有典型的导航。其中一页应该列出一些应用程序,我想知道实施方面的差异。为了简单起见,这里是迄今为止代码中的一些小片段:
应用模型
public class Application : BindableBase
{
private string _commandLine;
private string _name;
private string _smallIconSource;
public string CommandLine
{
get { return _commandLine; }
set { SetProperty(ref _commandLine, value); }
}
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
public string SmallIconSource
{
get { return _smallIconSource; }
set { SetProperty(ref _smallIconSource, value); }
}
}
ApplicationPage ViewModel
public class ApplicationPageViewModel : BindableBase
{
private ObservableCollection<Application> _applicationCollection;
public ApplicationPageViewModel()
{
// load some collection entries here
}
public ObservableCollection<Application> ApplicationCollection
{
get { return _applicationCollection; }
set
{
// if (_applicationCollection != null)
// _applicationCollection.CollectionChanged -= ApplicationCollectionChanged;
SetProperty(ref _applicationCollection, value);
// if (_applicationCollection != null)
// _applicationCollection.CollectionChanged += ApplicationCollectionChanged;
}
}
}
应用程序页面视图
<!-- ... -->
<ItemsControl ItemsSource="{Binding ApplicationCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- some kind of representation of applications -->
<Label Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- ... -->
在 Internet 上的一些代码示例中,尤其是在 SO 上的一些问题中,我看到有人问是否像我那样存储 ObservableCollection
的 ViewModels 而不是 Models - 我很好奇这一点您什么时候会选择其中一个版本而不是另一个版本?
此外,我想知道 Application
class 中的更改是否反映在 ApplicationPageViewModel
class 中,或者我是否必须挂接到 CollectionChanged
事件(正如我在 Brian Lagunas 的网络研讨会上看到的那样,我在其中看到了这种技术)。到目前为止,我只看到这个钩子进入 CollectionChanged
事件以调用 RaiseCanExecuteChanged
方法,如果手动 DelegateCommands
以防止在 [=21= 的以下实现时不必要的 bloat/calls ]s:
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
如果您的集合中的属性发生变化,我会使用 ViewModel。如果项目上的数据没有改变,那么使用 VM 或模型并没有真正的区别,这只是您喜欢的方式。 我个人喜欢将我的模型包装在 ViewModel 中,因为我可以轻松地添加组合属性以进行显示,而我不想直接在我的模型中使用这些属性。
如果您想在应用程序更改时对 ApplicationPageViewModel 执行某些操作,则必须
- 为应用程序使用 ViewModel
- 连接每个 Application ViewModel 的 INotifyPropertyChanged 事件
- 每次添加新的应用程序时,也将侦听器添加到此应用程序
如果您只想在添加或删除应用程序时执行一些操作,则不必使用 ViewModel,只需注册 ObservableCollection 的 CollectionChanged 事件