使用INotifyPropertyChanged自动通知属性更改



我一直在开发一个silverlight LOB应用程序,

在我的视图模型中,我有多达30个属性,当它们被改变时必须通知UI。

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

这仍然是令人难以置信的乏味,因为在我所有的setter中,我必须调用这个

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

这可能吗?


感谢大家的解决方案…我认为面向方面可能是这个问题最简洁的解决方案。我认为这将带来一场从Silverlight/RIA/EF/MVVM规范到更简单更简洁的方法的大迁徙。


哦,为了使这个问题对其他人尽可能有用,我要使用的AOP框架是PostSharp,他们有一个教程来实现这个:

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

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

<?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>

另存为

"My DocumentsVisual Studio 2010Code SnippetsVisual c# My Code Snippetsnp.snippet"

现在你可以简单地在代码编辑器中输入"np",按tab键两次,这个代码片段就会出现。输入类型名,按两次tab键,输入属性名,按回车键,就完成了。

当然AOP是可能的。

之类的
[Notify]
public string PropertyName{get; set;} 
可以使用AOP工具 将

转换为期望的结果。

你也可以应用属性像Notify到整个视图模型类,并使每个公共属性调用NotifyPropertyChanged

在google中有很多关于"AOP和NotifyPropertyChanged"的结果,但是我将指出我找到的关于这个主题的第一篇文章:http://sachabarber.net/?p=849

我通常最终编写自己的helper方法,以便我的属性可以有单行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这样的框架而有所不同。微,是否我的任何视图模型需要做额外的自定义工作时,一个属性的变化,等。下面是一个使用Caliburn的简单实现。微的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);
    }
}

相关内容

  • 没有找到相关文章

最新更新