Reputation: 41054
I have a class that I am binding to my view model. It is basically a struct full of displayable strings for the UI:
class DisplayVO
{
public string Title { get; set; }
public string Description { get; set; }
// ... about a dozen more properties
}
Basically the DisplayVO
wraps a bunch of properties that are bound to the UI. This works until one portion of the UI modifies a property (e.g. the user can edit the Description
) so I want to update the UI with the new modifications.
So what I would normally do is implement the INotifyPropertyChanged
interface and override each set
method to broadcast PropertyChanged(this, new PropertyChangedEventArgs(info));
I'm feeling lazy - is there a way to have this done for all members of the class? In Flex I could do:
[Bindable]
public class DisplayVO
{
private var Title:String;
private var Description:String;
}
and magically all of the properties of DisplayVO
would be wrapped to automatically broadcast changes without me having to write all of the boilerplate. Is there an equivalent for C# and WPF?
Upvotes: 2
Views: 190
Reputation: 2647
You should check out NotifyPropertyWeaver http://github.com/SimonCropp/NotifyPropertyWeaver it runs a post build task which does exactly what you are after.
Upvotes: 2
Reputation: 8802
I use a Property Declaration snippet that calls OnPropertyChanged. It also populates some Attributes from the System.ComponentModel name space...
Description: a brief phrase about what the property does
DisplayName: how the property should be labelled
DefaultValue: the initial value of the property
This snippet also uses the DebuggerStepThroughAttribute so that the debugger will not enter the getter and setter, but this should be removed if you don't want that effect...
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Full property declaration</Title>
<Shortcut>propfull</Shortcut>
<Description>Code snippet for property and backing field</Description>
<Author>GJV</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>The variable backing this property</ToolTip>
<Default>myProperty</Default>
</Literal>
<Literal>
<ID>desc</ID>
<ToolTip>What the property is about</ToolTip>
<Default>My description...</Default>
</Literal>
<Literal>
<ID>dispname</ID>
<ToolTip>Column header</ToolTip>
<Default>DisplayName</Default>
</Literal>
<Literal>
<ID>defaultvalue</ID>
<ToolTip>Default value</ToolTip>
<Default>""</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[private $type$ $field$;
[Description("$desc$"), DisplayName("$dispname$"), DefaultValue($defaultvalue$)]
public $type$ $property$
{
[DebuggerStepThrough]get{return $field$;}
[DebuggerStepThrough]set
{
if(value!=$field$)
{
$field$ = value;
OnPropertyChanged("$property$");
}
}
}
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
The Description Attribute is meant to be extracted and used for ToolTip text, but it can also provide some documentation value.
This snippet assumes that your base view model class has a method like this...
protected void OnPropertyChanged(string propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 1
Reputation: 2174
you could write a snippet that fills in the boilerplate. Here's one that I use ( I have a method, OnPropertyChanged() that broadcasts the event:
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<Header>
<Title>ObservableProperty</Title>
<Author>Scott Austen</Author>
<Shortcut>#ObsProp</Shortcut>
<Description>Inserts property definition with private backing field, calling RaisePropertyChanged</Description>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>Type</ID>
<Default>Type</Default>
</Literal>
<Literal>
<ID>PropertyName</ID>
<Default>P</Default>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[public $Type$ $PropertyName$
{
get { return _$PropertyName$; }
set
{
_$PropertyName$ = value;
OnPropertyChanged("$PropertyName$");
}
}
private $Type$ _$PropertyName$;]]>
</Code>
</Snippet>
</CodeSnippet>
then all you need to do is type obsprop TAB TAB {type} TAB TAB {propertyName} ENTER.
Upvotes: 1