A short way to define properties for bind MVVM data in C # WPF

Is there a short way to define properties in a ViewModel to bind data in C # WPF? The following property definition is very verbose, especially when there are many properties:

private bool mSomeProperty; public bool SomeProperty { get { return this.mSomeProperty; } set { if (value != this.mSomeProperty) { this.mSomeProperty = value; OnPropertyChanged(new PropertyChangedEventArgs("SomeProperty")); } } } 
+4
source share
7 answers

In C #, I would like to create a base class and add some helper methods to it. Then I make my ViewModels go out of it. This is from memory, but it is something like this:

 public class Observable : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void SetProperty<T>(ref T backingField, T newValue, string propertyName) { if (Equals(backingField, newValue)) return; backingField = newValue; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } 

And, in use:

 public class MyClass : Observable { private bool m_someProperty; public bool SomeProperty { get { return m_someProperty; } set { SetProperty(ref m_someProperty, value, "SomeProperty"); } } } 
+3
source

Here you can find some ideas:

Implementing and using INotifyPropertyChanged https://github.com/jbe2277/waf/wiki/Implementing-and-usage-of-INotifyPropertyChanged

+2
source

You can always use DependencyProperties and miss your heart ...

+1
source

If you use the Delphi Prism language (Pascal .NET language), you simply add the notify keyword, and the compiler automatically implements INotifyPropertyChanged and writes all the boilerplate code for you:

 property SomeProperty: bool; notify; 
0
source

I think you won’t get a property declaration much less than this, at least not with β€œregular” methods. You can use a lock interceptor to take care of this.

 public class MyViewModel : INotifyPropertyChanged { public event PropertyChanged; public void FirePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(propertyName); } public virtual string MyProperty { get; set; } public virtual string MyProperty2 { get; set; } } 

The interceptor will need to fire the event of the changed property:

 public class PropertyChangedInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { //Pseudo code if (invocation.Method is Property Setter) { Call FirePropertyChanged of invocation.InvocationTarget ; } } } 

You just need to make sure that your view model properties are virtual, and your view model is always a proxy server and not the view model itself.

Best wishes

0
source

You can consider PostSharp , which allows you to decorate a property (which you could then override as the auto property) and enter a string in the setter that fires the NotifyPropertyChanged event. An added benefit is that you get rid of the string that matches the property name.

This is not ideal, because you need this tool, and it will not be immediately obvious if you look at the code later, but it definitely makes it more accurate.

I was hoping that MSFT would add such an attribute to C # 4, but I think we will have to wait for C # 5, if at all.

0
source

This answer is very similar to Joe White's answer above, but the code is a bit more concise and perhaps a little more understandable, as property names should not be sent as a string in quotation marks.

Using the CallerMemberName functionality, there are two ways to do this. One is to create an abstract class that contains IPropertyNotifyChanged code, and another approach is to include the IPropertyNotifyChanged support code in a real class. I usually use both depending on the context.

Here's what the results look like when using an abstract class:

 public abstract class PropertyNotifier: INotifyPropertyChanged { #region INotifyPropertyChanged support code public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) { bool result = false; if (!Object.Equals(storage, value)) { storage = value; OnPropertyChanged(propertyName); result = true; } return result; } #endregion INotifyPropertyChanged support code } 

And in use:

 public interface IPerson { String FirstName { get; set } String LastName { get; set } } public class Person : PropertyNotifier, IPerson { private string _FirstName; private string _LastName; public String FirstName { get { return _FirstName; } set { SetProperty(ref _FirstName, value); } } public String LastName { get { return _LastName; } set { SetProperty(ref _LastName, value); } } } 

Hope this helps!

0
source

All Articles