首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理MVVM ViewModel中的“SelectedItemChanged”事件?

如何处理MVVM ViewModel中的“SelectedItemChanged”事件?
EN

Stack Overflow用户
提问于 2010-03-14 06:31:36
回答 3查看 1.6K关注 0票数 4

我有一些依赖于设置的两个属性的逻辑,因为当两个属性都有值时,它就会执行。例如:

代码语言:javascript
复制
private void DoCalc() {
  if (string.IsNullOrEmpty(Property1) || string.IsNullOrEmpty(Property2))
    return;
  Property3 = Property1 + " " + Property2;
}

每次更改Property1或Property2时都需要执行该代码,但我很难弄清楚如何以一种在风格上可接受的方式来执行它。以下是我所看到的选择:

1)从ViewModel调用方法

我对此在概念上没有问题,因为逻辑仍然在ViewModel中-我不是一个“不隐藏代码”的纳粹分子。然而,“触发器”逻辑(当任何一个属性改变时)仍然在UI层,这是我不喜欢的。代码幕后将如下所示:

代码语言:javascript
复制
void ComboBox_Property1_SelectedItemChanged(object sender, RoutedEventArgs e) {
  viewModel.DoCalc();
}

2)从属性设置器调用方法

这种方法看起来最“纯粹”,但它看起来也很丑陋,似乎逻辑是隐藏的。它看起来像这样:

代码语言:javascript
复制
public string Property1 {
  get {return property1;}
  set {
    if (property1 != value) {
      property1 = value;
      NotifyPropertyChanged("Property1");
      DoCalc();
    }
  }
}

3)钩入PropertyChanged事件

我现在认为这可能是正确的方法,但在实现视图模型中挂钩属性更改事件感觉很奇怪。它看起来像这样:

代码语言:javascript
复制
public ViewModel() {
  this.PropertyChanged += new PropertyChangedEventHandler(ViewModel_PropertyChanged);
}

void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) {
  if (e.PropertyName == "Property1" || e.PropertyName == "Property2") {
    DoCalc();
  }
}

因此,我的问题是,如果您正在浏览一些具有该需求的源代码,您更希望看到实现哪种方法(以及为什么?)感谢您的任何意见。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-14 10:29:00

我不认为在二传手中做这件事很丑陋...实际上,这可能是您提到的3种方法中最好的一种,因为当您阅读代码时,您会立即看到更改Property1Property2的值将重新计算Property3;对于其他两种方法,这一点并不明显。

但是,我不会使用这两个选项。根据Property1Property2的说法,我认为更好的方法是将Property3设为只读,然后在getter中计算它的值:

代码语言:javascript
复制
public string Property3
{
    get { return Property3 = Property1 + " " + Property2; }
}

这样,在Property1Property2的setter方法中,您也只需要为Property3调用NotifyPropertyChanged

票数 3
EN

Stack Overflow用户

发布于 2010-03-17 02:20:35

(2)是我通常的做法。

也就是说,这让我想知道是否有另一种方法可以使用Rx框架来做这类事情:http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

这就是我想出来的(警告-不要这样做!);

代码语言:javascript
复制
public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        var o1 =
            Observable.FromEvent<PropertyChangedEventArgs>(this, "PropertyChanged");
        o1.Subscribe(e => Debug.WriteLine(e.EventArgs.PropertyName));
        var o2 = o1.SkipWhile(e => e.EventArgs.PropertyName != "Property1");
        var o3 = o1.SkipWhile(e => e.EventArgs.PropertyName != "Property2");
        var o4 = o1.SkipWhile(e => e.EventArgs.PropertyName != "Result");
        var o5 = Observable.CombineLatest(o2, o3, (e1, e2) => DoStuff()).TakeUntil(o4);
        o5.Subscribe(o => Debug.WriteLine("Got Prop1 and Prop2"));
    }

    public string DoStuff()
    {
        return Result = string.Concat(Property1, Property2);                
    }

    private string _property1;
    public string Property1
    {
        get { return _property1; }
        set
        {
            _property1 = value;
            OnNotifyPropertyChanged("Property1");
        }
    }
    private string _property2;
    public string Property2
    {
        get { return _property2; }
        set
        {
            _property2 = value;
            OnNotifyPropertyChanged("Property2");
        }
    }
    private string _result;
    public string Result
    {
        get { return _result; }
        set
        {
            _result = value;
            OnNotifyPropertyChanged("Result");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnNotifyPropertyChanged(string name)
    {
        var handler = PropertyChanged;
        if(handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2010-03-14 15:07:03

是的,@Thomas是对的。方法2是WPF环境中的完美方法。假设您已将ListBox.SelectedValue TwoWay绑定添加到Property1

您的(1)是无效的,因为这会将业务逻辑暴露到视图中。(3)是一个不必要的事件处理,无论如何都是由Property1设置器代码触发的。所以最好直接从Setter调用它。所以MVVM方式是(2)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2440296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档