制作适合财产变更通知的课程

时间:2015-06-08 20:43:22

标签: c# wpf

要在WPF中实现数据绑定,根据MS,“类需要提供适当的属性更改通知”。 [ref here]

AFAIK,设置此项的一部分意味着采取以下步骤,如果尚未在课程中设置(MSDN上的参考this article):

  • 当属性发生变化时,他们需要调用方法来引发事件
    • 这意味着必须更改自动实现的属性,以便它们使用私有支持字段,因此set可以更改属性并调用方法来引发事件。
  • 该类需要实现INotifyPropertyChanged。
  • 该类需要声明PropertyChangedEventHandler事件。
  • 事件需要以这样的方式提出:

...

// Create the OnPropertyChanged method to raise the event 
protected void OnPropertyChanged(string name)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(name));
    }
}

如果我已经有许多现有的类没有采取任何这些步骤,那么更改这些类的最佳方法是什么,以便只在需要时才更改以使它们符合这些标准

5 个答案:

答案 0 :(得分:4)

我很喜欢C#5中[CallerMemberName]的实现,如here所述

protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
    ...
}

只需使参数可选并使用CallerMemberName属性进行装饰。

您的财产现在看起来像这样:

public DateTime Time
{
    get { return this.model.DateTime; }
    set
    {
        this.model.DateTime = value;
        NotifyPropertyChanged();
    }
}

答案 1 :(得分:4)

如果您想要最小可能的代码影响解决方案,那么您需要Fody PropertyChanged weaver。它作为带有[ImplementPropertyChanged]的NuGet包安装,或通过VS包管理器对话安装。

安装完成后,您可以使用(defun show (&rest items) (dolist (i items) (prin1 i) (fresh-line)) (finish-output)) (locally (declare #+sbcl(sb-ext:muffle-conditions style-warning)) (handler-bind (#+sbcl(style-warning #'muffle-warning)) (load "load.lisp") )) (show (interval 5) (interval 20) (interval 500)) 属性标记一个类,并且您的工作基本完成。编织者将通过操作生成的IL来在编译时添加相关的事件调用 ,这意味着您不必在代码中显式实现接口或事件调用。您也可以保留自动实现的属性语法!

链接的文档提供了更高级案例的详细信息,但根据我的经验,开箱即用的行为足以满足几乎所有需求。

答案 2 :(得分:1)

我通常喜欢使用此实现来通知我的属性中的更改

class IWillNotifyYou : INotifyPropertyChanged
{
    private int _firstProperty;
    public int FirstProperty
    {
        get { return _firstProperty; }
        set
        {
            if (value != _firstProperty)
            {
                _firstProperty = value;
                OnPropertyChanged("FirstProperty");
            }
        }
    }

    private string _secondProperty;
    public string SecondProperty
    {
        get { return _secondProperty; }
        set
        {
            if (value != _secondProperty)
            {
                _secondProperty = value;
                OnPropertyChanged("SecondProperty");
            }
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }


    public event PropertyChangedEventHandler PropertyChanged;
}

请注意,您可以使用FirstPropertyChanged等属性的名称创建一个专门的事件

答案 3 :(得分:0)

添加":INotifyPropertyChanged"在你的课程定义之后:

Public class Test : INotifyPropertyChanged 
{
}

接受ReSharpers建议以实现此类的接口(您可能必须安装ReSharper才能使其工作)。

然后,在任何属性的setter中,添加:

OnPropertyChanged("PropertyName")

这意味着您现在可以将XAML中的属性绑定到此类中的此属性。

答案 4 :(得分:0)

您需要确定现有课程现在扮演的角色。使用MVVM(Model-View-ViewModel),WPF最有用。确定当前类的角色将有助于确定需要更改的内容(如果有的话)。

假设您现有的类是Business Objects,由您决定是否需要实现INotifyPropertyChanged。通过绑定到ViewModel,WPF最容易使用。 ViewModel实际上处理View(WPF屏幕)和Model之间的数据。

Model可以实现INotifyPropertyChanged,但并非如此。 ViewModel将保存特定屏幕(或控件)所需的任何属性,并且可能是您要探索的路径,因此您不会完全180 *您现有的业务对象。