WPF MVVM通知 [英] WPF MVVM Notification

查看:218
本文介绍了WPF MVVM通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的专家,我需要你的帮助。我的ViewModel中有一组孩子,每个孩子都有一些属性。我使用ListBox模板项创建了一个接口。子对象的每个属性都使用控件绑定,例如使用下拉列表或文本框。现在我想通知我的ViewModel,如果在子对象的any属性中发生任何更改。





问候

解决方案

有多种方法可以实现这一点(以及各种MVVM框架,在某种程度上为你完成),这一切都取决于上下文。

如果你有一个相当静态的子集(静态为拥有的视图模型的生命周期),那么将欠视图模型连接到

INotifyPropertyChanged.PropertyChanged 每个孩子的事件可能适合你。



另一方面,如果孩子的名单发生变化,那么拥有的视图模型将不得不订阅和取消订阅儿童活动然后可能有点乱。



考虑以下简单示例;



通知程序

 使用 System.ComponentModel; 
命名空间 WpfApplication {
public class 通知程序:INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
受保护 void 通知( string propertyName){
var handler = PropertyChanged;
if (handler!= null
handler( this new PropertyChangedEventArgs(propertyName));
}
}
}



ChildModel

 命名空间 WpfApplication {
public class ChildModel {
private readonly string 名称;
public string MutableValue { get ; set ; }

public ChildModel( string name, string mutableValue){
this .name = name;
MutableValue = mutableValue;
}

public string 名称{
< span class =code-keyword> get { return name; }
}
}
}



MainModel

 使用 System.Collections.Generic; 

命名空间 WpfApplication {
public class MainModel {

private readonly < span class =code-keyword> string name;
private readonly IEnumerable< ChildModel>儿童;

public MainModel( string name,IEnumerable< ChildModel> children){
.name = name;
.children = children;
}

public string 名称{
< span class =code-keyword> get { return name; }
}

public IEnumerable< ChildModel>儿童{
获取 {返回儿童; }
}
}
}



ChildViewModel

 命名空间 WpfApplication {
public class ChildViewModel:通知程序{
private readonly ChildModel模型;

public ChildViewModel(ChildModel模型){
.model =模型;
}

public string MutableValue {
< span class =code-keyword> get { return model.MutableValue; }
set {
if value == model.MutableValue)
return ;

model.MutableValue = value ;
通知( MutableValue);
}
}
}
}



MainViewModel

 使用 System.Collections.Generic; 
使用 System.Linq;
使用 System.ComponentModel;

命名空间 WpfApplication {
public class MainViewModel {
private readonly MainModel模型;
private readonly IEnumerable< childviewmodel>儿童;

public MainViewModel(MainModel模型){
this .model =模型;

children = model.Children.Select(child = > new ChildViewModel (子))ToList()。
foreach var child in 孩子们){
child.PropertyChanged + = OnChildPropertyChanged;
}
}

私有 void OnChildPropertyChanged( object sender,PropertyChangedEventArgs e){
var child = sender as ChildViewModel;
// 在这里做一些很棒的事情!
}

public string 名称{
get { return model.Name; }
}

public IEnumerable< childviewmodel>儿童{
获取 {返回儿童; }
}
}
}
< / childviewmodel > < / childviewmodel >





在这种情况下来自<$ c $的事件c> ChildViewModel 由拥有的视图模型 MainViewModel 监视,并且连接到事件是 MainViewModel 并在其构造函数中完成,因为它从子模型创建视图模型。



再次;如果你需要这样的设置可能会变得凌乱;



  • 动态添加/删除孩子
  • 有很多属性 ChildViewModel MainViewModel 需要根据更改的属性执行不同的操作。
  • 孩子的类型各不相同




希望这会有所帮助,

Fredrik


Hi dear experts I need your help. I have a collection of childs in my ViewModel, each child has some properties. I have created an interface using ListBox template items. Each property of child object is bind with a control let say with a dropdown or with a text box. Now I want to notify my ViewModel if any change occurs in the any property of a child object.


Regards

解决方案

There are various ways of achieving this (and various MVVM frameworks that does it for you, to a degree) and it all depends on the context.
If you have a fairly static set of children (static as is static for the life of the owning view model) then having the owing view model connect to the
INotifyPropertyChanged.PropertyChanged event on each child might work for you.

If on the other hand the list of children changes so that the owning view model would have to subscribe and unsubscribe to child events then that might be a little messy.

Consider the following simple example;

Notifier

using System.ComponentModel;
namespace WpfApplication {
    public class Notifier : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void Notify(string propertyName) {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}


ChildModel

namespace WpfApplication {
    public class ChildModel {
        private readonly string name;
        public string MutableValue { get; set; }

        public ChildModel(string name, string mutableValue) {
            this.name = name;
            MutableValue = mutableValue;
        }

        public string Name {
            get { return name; }
        }
    }
}


MainModel

using System.Collections.Generic;

namespace WpfApplication {
    public class MainModel {

        private readonly string name;
        private readonly IEnumerable<ChildModel> children;

        public MainModel(string name, IEnumerable<ChildModel> children) {
            this.name = name;
            this.children = children;
        }

        public string Name {
            get { return name; }
        }

        public IEnumerable<ChildModel> Children {
            get { return children; }
        }
    }
}


ChildViewModel

namespace WpfApplication {
    public class ChildViewModel : Notifier {
        private readonly ChildModel model;

        public ChildViewModel(ChildModel model) {
            this.model = model;
        }

        public string MutableValue {
            get { return model.MutableValue; }
            set {
                if (value == model.MutableValue) 
                    return;

                model.MutableValue = value;
                Notify("MutableValue");
            }
        }
    }
}


MainViewModel

using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;

namespace WpfApplication {
    public class MainViewModel {
        private readonly MainModel model;
        private readonly IEnumerable<childviewmodel> children;

        public MainViewModel(MainModel model) {
            this.model = model;

            children = model.Children.Select(child => new ChildViewModel(child)).ToList();
            foreach (var child in children) {
                child.PropertyChanged += OnChildPropertyChanged;
            }
        }

        private void OnChildPropertyChanged(object sender, PropertyChangedEventArgs e) {
            var child = sender as ChildViewModel;
            // Do something awesome here!
        }

        public string Name {
            get { return model.Name; }
        }

        public IEnumerable<childviewmodel> Children {
            get { return children; }
        }
    }
}
</childviewmodel></childviewmodel>



In this case the events from the ChildViewModel are monitored by the owning view model, MainViewModel, and the hooking up to the event is the responibility of the MainViewModel and is done in its constructor as it creates view models from models of the children.

Again; a setup like this might turn messy if you need to;


  • Dynamically add/remove children
  • There are many properties on the ChildViewModel and the MainViewModel needs to do different things depending on which property was changed.
  • The type of children vary


Hope this helps,
Fredrik


这篇关于WPF MVVM通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆