Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVVM中的ObservableCollection事件传播和正确使用_C#_Wpf_Mvvm_Observablecollection_Inotifypropertychanged - Fatal编程技术网

C# MVVM中的ObservableCollection事件传播和正确使用

C# MVVM中的ObservableCollection事件传播和正确使用,c#,wpf,mvvm,observablecollection,inotifypropertychanged,C#,Wpf,Mvvm,Observablecollection,Inotifypropertychanged,我进入了MVVM,从Prism框架开始,在我的示例应用程序中,我有典型的导航。其中一页应该列出一些应用程序,我想知道实现中的差异。为了简单起见,这里有一些到目前为止代码中的小片段: 应用程序模型 public class Application : BindableBase { private string _commandLine; private string _name; private string _smallIconSource; public st

我进入了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); }
    }
}
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;
        }
    }
}
应用程序页面视图模型

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); }
    }
}
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;
        }
    }
}

如果集合中的属性发生更改,我将使用ViewModels。如果一个项目上的数据没有改变,那么如果您使用虚拟机或模型,这并没有真正的区别,而且这正是您喜欢的方式。 我个人喜欢在ViewModels中包装我的模型,因为我可以轻松地添加用于显示的组合属性,而我不希望直接在模型中包含这些属性

如果要在应用程序更改时对ApplicationPageViewModel执行某些操作,必须

  • 对应用程序使用ViewModel
  • 连接每个应用程序ViewModel的INotifyPropertyChanged事件
  • 每次添加新应用程序时,也要将侦听器添加到此应用程序

如果您只想在添加或删除应用程序时执行某些操作,则不必使用ViewModel,只需注册ObservableCollection的CollectionChanged事件即可,这样就可以解决一些问题。我仍然想知道,如果您使用ViewModels来包含一些组合属性,那么您肯定依赖于Facade模式,不是吗?这种方法是否会使可维护性变得更复杂,并迫使您编写重复的代码来访问您不想隐藏的相同属性?对于我当前的项目,我正在为ViewModels使用DynamicObject包装器,其中我只想添加一些属性或与视图相关的功能。这不是最快的方法,但非常方便,因为我不必为属性重复代码,只需为ViewModel指定模型。对于我的模型,我无法注册更改,因为它没有实现INotifyPropertyChanged接口,只保存数据。除了INotifyPropertyChanged之外,如果ObservableCollections中有ObvservableCollections,有时还需要添加PropertyChanged=>OnCollectionChanged。我尝试将其自动化,但没关系,手动实现它非常简单和直接。您的问题基本上是如何告知更改的集合中的项目。我可以想到:1)将ViewModel实例传递给每个项(构造函数或任何东西),项可以订阅ViewModel的某个事件,事件由ViewModel(甚至由项)引发2)ViewModel处理所有更改和通知(通过调用集合更改时的每个项方法)。如果您实现了
INotifyPropertyChanged
(这是您将要收听的事件),则框中会给出方法(1)。