Why there is no shorthand for PropertyChanged in MVVM Light
Where there is no shorthand in MVVM Light each time we call PropertyChanged in the setter, something like in flex [Binda开发者_StackOverflow社区ble]:
[PropertyChanged]
public bool IsEditable { .... }
why do we have to write PropertyChanged("IsEditable") everytime, its error prone, where it can be defaulted.
I decided against adding this to MVVM Light because the solutions involve either Reflection (which slows down the perf) or IL weaving (which is "magic" and as such goes against the principles of MVVM Light, which is to be light and simple to understand.
To "fight" against the issues you mention, I have three tools in MVVM Light:
- Code snippet to create a "bindable" property automatically. Simply type mvvminpc and then expand the snippet. It is an easy way to avoid writing the code.
- The "magic string" is declared as a public const string on the VM class. This way you avoid typos.
- At debug time, the ViewModelBase class automatically checks if the property name exists on the VM class when RaisePropertyChange is called. This catches typos early in the development game.
With these three tools, it is my evaluation that other mechanisms are not necessary. However, by popular demand, I will add a way to RaisePropertyChanged using a lambda expression (eg RaisePropertyChanged(vm => vm.MyProperty)). This will be, of course, optional if you don't want to have the perf hit that this implies.
Also, I have been talking this year to influencial people (including Anders Heljsberg) and underlined that it would be nice to have this baked in the framework (or even in the language). That would be the most satistying solution (because of the perf optimizations that MSFT could do on that), but that will take time, obviously (if it ever happens).
Cheers, Laurent
You can create strongly typed INotifyPropertyChanged behavior. Which would allow you to do something like...
RaiseChanged(() => this.PropertyName);
This cannot be done without rewriting the IL to insert PropertyChanged
calls. (Or using extremely slow proxies, and building inherited types at runtime)
You're looking for PostSharp.
You could also create a code snippet that raises the event:
<?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>
For better or for worse, it's not possible to implement automatic property changed notifications using compile-time attributes in the way you suggest. However, in MVVM Light when running in the debug build, your PropertyChanged
calls will be validated to ensure they correspond to real properties, which means refactoring the property name without changing the string will be caught in the debug build.
精彩评论