我一直在开发一个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);
}
}