使用INotifyPropertyChanged自动更改属性更改?

时间:2011-11-02 11:58:20

标签: silverlight xaml binding inotifypropertychanged

我一直在研究Silverlight LOB应用程序,

在我的视图模型中,我有多达30个属性,必须在更改时通知用户界面。

我的ViewModel基类实现了INotifyPropertyChanged并且有一个名为OnPropertyChanged(string propName)的包装器方法

这仍然令人难以置信的乏味,因为在我所有的安装人员中我都要称之为。

我希望能够在某些属性/装饰类的所有成员上自动触发它。

这可能吗?


感谢大家的解决方案..我认为方面导向可能是解决这个问题的最简洁的解决方案。我认为这将带来一个远离Silverlight / RIA / EF / MVVM规范的大规模解决方案更简洁更简洁的方法..


哦也是为了让这个问题对其他人有用,我想要的AOP框架是PostSharp,他们有一个实现这个目的的教程:

http://www.sharpcrafters.com/solutions/notifypropertychanged

3 个答案:

答案 0 :(得分:1)

没有减少所需代码量的好方法。但是,每个属性构造中唯一不同的是它的名称和类型。因此它是一个很好的代码片段。以下是一个示例代码段: -

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Notify Property</Title>
      <Shortcut>np</Shortcut>
      <Description>Code snippet for a property that calls the INotifyPropertyChange event</Description>
      <Author>Coding Bloke</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>property</ID>
          <ToolTip>Property name</ToolTip>
          <Default>MyProperty</Default>
        </Literal>
        <Literal>
          <ID>type</ID>
          <ToolTip>Property type</ToolTip>
          <Default>string</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[private $type$ _$property$;
        public $type$ $property$
        {
            get { return _$property$; }
            set
            {
                _$property$ = value;
                OnPropertyChanged("$property$");
            }
        }
]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

将上述内容保存为

“我的文档\ Visual Studio 2010 \ Code Snippets \ Visual C#\ My Code Snippets \ np.snippet”

现在您只需在代码编辑器中输入“np”,按Tab键两次,即可显示此代码段。输入类型名称,按两次选项卡,输入属性名称,按回车键即可完成。

答案 1 :(得分:0)

当然可以使用AOP。

类似

[Notify]
public string PropertyName{get; set;} 
使用AOP工具

可以将

转换为所需的结果

您还可以将Notify之类的属性应用于整个viewmodel类,并使每个公共属性调用NotifyPropertyChanged

谷歌的“AOP和NotifyPropertyChanged”有很多结果,但我会在第一篇文章中指出我在这个主题上找到的结果:http://sachabarber.net/?p=849

答案 2 :(得分:0)

我通常最终编写自己的帮助方法,以便我的属性可以有单行getter和setter。这消除了大部分的痛苦:

public string Name {
    get { return _name; }
    set { SetProperty(ref _name, value, () => Name); }
}
public int Value {
    get { return _value; }
    set { SetProperty(ref _value, value, () => Value); }
}

我的SetProperty方法的实现将取决于我是否使用像Prism或Caliburn.Micro这样的框架,我的任何视图模型是否需要在属性更改时执行额外的自定义工作等。这是一个简单的实现使用Caliburn.Micro的PropertyChangedBase:

public class Observable : PropertyChangedBase
{
    protected void SetProperty<T>(ref T backingField, T newValue,
        Expression<Func<T>> property)
    {
        if (Equals(backingField, newValue))
            return;
        backingField = newValue;
        NotifyOfPropertyChange(property);
    }
}