INotifyPropertyChanged and Auto-Properties
In .NET 4.5 and higher it can be made somewhat shorter:
private int unitsInStock;
public int UnitsInStock
{
get { return unitsInStock; }
set { SetProperty(ref unitsInStock, value);}
}
It's something you would have to code yourself. The closest you could get would be something like this implementation on Code Project that uses a custom attribute and aspect orientated methods to give this syntax:
[NotifyPropertyChanged]
public class AutoWiredSource
{
public double MyProperty { get; set; }
}
Someone once proposed on Microsoft Connect a change to the C# specification implement this:
class Person : INotifyPropertyChanged
{
// "notify" is a context keyword, same as "get" and "set"
public string Name { get; set; notify; }
}
But the proposal has been now closed.
There's no built-in mechanism to do this. Something like PostSharp would likely be able to add something like this for you (or Mark Gravell's HyperDescriptor, if you're just interested in making this databinding-aware).
I tried other ways first using:
- BindableBase
- DynamicViewModel
Those methods work, however I've still had to muddy the accessor methods of all properties in the Model or use a dynamic
object which kills your auto-completion when coding. It's also worth mentioning that WinForms don't support binding to dynamic objects unfortunately.
Solution
Eventually I came across ReactiveUI.Fody. It's a simple to use solution using Fody and ReactiveUI. I used this in my WPF project successfully.
It weaves in the required boilerplate code, RaisePropertyChanges
and ObservableAsPropertyHelper
, at compile time.
Project Dependencies
https://github.com/kswoll/ReactiveUI.Fody
I installed the following packages in my project with NuGet:
<packages>
<package id="Fody" version="2.0.7" targetFramework="net452" developmentDependency="true" />
<package id="reactiveui" version="7.4.0" targetFramework="net452" />
<package id="ReactiveUI.Fody" version="2.2.11" targetFramework="net452" />
<package id="reactiveui-core" version="7.4.0" targetFramework="net452" />
<package id="Rx-Core" version="2.2.5" targetFramework="net452" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net452" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net452" />
<package id="Rx-Main" version="2.2.5" targetFramework="net452" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net452" />
<package id="Rx-XAML" version="2.2.5" targetFramework="net452" />
<package id="Splat" version="1.6.0" targetFramework="net452" />
</packages>
Fody Setup
You'll need to create a FodyWeavers.xml file in the top level of you project so it looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<ReactiveUI/>
</Weavers>
Usage
You just set your Model classes to inherit off ReactiveObject
and add the
[Reactive]
attribute above any property you want to notify of changes.
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace name.domain.some{
class SomeClass : ReactiveObject {
[Reactive]
public string SomeProperty { get; set; }
}
}
Job done! Rebuild your project and check the output window in Visual Studio. You should see some lines outputted from Fody as it processes your annotated Model classes and injects the appropriate boilerplate code. It should look something like this:
Further Info
More useful info can be found here.