【发布时间】:2010-12-29 22:15:40
【问题描述】:
每次我们在 setter 中调用 PropertyChanged 时,MVVM Light 中都没有简写,类似于 flex [Bindable]:
[PropertyChanged]
public bool IsEditable { .... }
为什么每次都要写PropertyChanged("IsEditable"),容易出错,哪里可以默认。
【问题讨论】:
标签: .net mvvm mvvm-light
每次我们在 setter 中调用 PropertyChanged 时,MVVM Light 中都没有简写,类似于 flex [Bindable]:
[PropertyChanged]
public bool IsEditable { .... }
为什么每次都要写PropertyChanged("IsEditable"),容易出错,哪里可以默认。
【问题讨论】:
标签: .net mvvm mvvm-light
我决定不将其添加到 MVVM Light,因为解决方案涉及反射(减慢性能)或 IL 编织(这是“魔术”,因此违反了 MVVM Light 的原则,即轻且简单易懂。
为了“对抗”你提到的问题,我在 MVVM Light 中有三个工具:
有了这三个工具,我的评估是不需要其他机制。但是,根据大众的需求,我将使用 lambda 表达式向 RaisePropertyChanged 添加一种方法(例如 RaisePropertyChanged(vm => vm.MyProperty))。当然,如果您不想获得这意味着的性能命中,这将是可选的。
此外,我今年一直在与有影响力的人(包括 Anders Heljsberg)交谈,并强调如果能在框架中(甚至在语言中)实现这一点会很好。这将是最令人满意的解决方案(因为 MSFT 可以对此进行性能优化),但这显然需要时间(如果有的话)。
干杯, 洛朗
【讨论】:
您可以创建strongly typed INotifyPropertyChanged 行为。这将允许您执行类似...
RaiseChanged(() => this.PropertyName);
【讨论】:
如果不重写 IL 以插入 PropertyChanged 调用,则无法完成此操作。 (或者使用极慢的代理,并在运行时构建继承的类型)
您正在寻找PostSharp。
您还可以创建一个引发事件的代码 sn-p:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Property With Change Event</Title>
<Shortcut>propc</Shortcut>
<Description>Code snippet for property that calls OnPropertyChanged and XML description</Description>
<Author>SLaks</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<ToolTip>Property type</ToolTip>
<Default>string</Default>
</Literal>
<Literal>
<ID>property</ID>
<ToolTip>Property name</ToolTip>
<Default>MyProperty</Default>
</Literal>
<Literal>
<ID>field</ID>
<ToolTip>Backing field name</ToolTip>
<Default>myProperty</Default>
</Literal>
<Literal>
<ID>desc</ID>
<ToolTip>The description of this property</ToolTip>
<Default>...</Default>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[$type$ $field$;
///<summary>Gets or sets $desc$.</summary>
public $type$ $property$ {
get { return $field$; }
set { $field$ = value; OnPropertyChanged("$property$"); }
}
$end$]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
【讨论】:
无论好坏,都不可能按照您建议的方式使用编译时属性实现自动属性更改通知。但是,在调试版本中运行时,在 MVVM Light 中,将验证您的 PropertyChanged 调用以确保它们对应于真实属性,这意味着在不更改字符串的情况下重构属性名称将在调试构建。
【讨论】: