Shorter code to trigger property changes

I have a class with dozens of properties that need to raise properties, changed events, currently my code looks something like

public class Ethernet : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string timeStamp;

    public string TimeStamp
    {
        get { return timeStamp; }
        set
        {
            timeStamp = value;

            if(PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("TimeStamp"));
        }
    }
}

Is there a shorter way in C # to write such code, I do excessive copy / paste operations for each property, and I believe there should be a better way.

+4
source share
4 answers

(Suppose this is a short comment, but apparently I'm not allowed to post it, but Mods, please feel free to comment on the comment below.)

, . . INotifyPropertyChanged?, , , .

    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null) handler(this, new PropertyChangedEventArgs("TimeStamp"));

. INotifyPropertyChanged - ?, # 6.0.

    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TimeStamp"));
+6

: fooobar.com/questions/78945/...

:

public class Ethernet : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string timeStamp;

    public string TimeStamp
    {
        get { return timeStamp; }
        set { this.NotifySetProperty(ref timeStamp, value, () => this.TimeStamp); }
    }
}

, .

+1

In the MVVM template, the change / ing properties are often used, and a typical basic solution is as follows:

  public class ViewModelBase : INotifyPropertyChanged
  {
     public event PropertyChangedEventHandler PropertyChanged;

     protected void FirePropertyChanged([CallerMemberName] string propertyName = null)
     {
        if (propertyName == null)
           throw new ArgumentNullException("propertyName");
        try
        {
           this.OnPropertyChanged(propertyName);
        }
        catch (Exception exception)
        {
           Trace.TraceError("{0}.OnPropertyChanged threw {1}: {2}", this.GetType().FullName, exception.GetType().FullName, exception);
        }
     }
     protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
     {
        var handler = PropertyChanged;
        if (handler != null)
        {
           handler(this, new PropertyChangedEventArgs(propertyName));
        }
     }
  }

 public class Ethernet : ViewModelBase
  {
     private DataTime timeStamp;

     public DateTime TimeStamp
     {
        get
        {
           return timeStamp;
        }
        set
        {
           timeStamp = value;
           FirePropertyChanged();
        }
     }
  }
0
source

I love this class:

[Serializable]
public class PropertyChangedBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual bool SetProperty<T>(T value, ref T field, Expression<Func<object>> property)
    {
        return SetProperty(value, ref field, GetPropertyName(property));
    }

    protected virtual bool SetProperty<T>(T value, ref T field, [CallerMemberName] string propertyName = null)
    {
        if (field == null || !field.Equals(value))
        {
            field = value;
            OnPropertyChanged(propertyName);
            return true;
        }
        return false;
    }

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public void OnPropertyChanged(Expression<Func<object>> property)
    {
        OnPropertyChanged(GetPropertyName(property));
    }

    protected string GetPropertyName(Expression<Func<object>> property)
    {
        var lambda = property as LambdaExpression;
        MemberExpression memberExpression;

        var unaryExpression = lambda.Body as UnaryExpression;
        if (unaryExpression != null)
        {
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = (MemberExpression) lambda.Body;
        }

        var propertyInfo = memberExpression?.Member as PropertyInfo;
        return propertyInfo?.Name ?? string.Empty;
    }
}

The great advantage of this is that it checks to see if the value has changed. This minimizes update calls for presentation. For your example, this might look like this:

public class Ethernet : PropertyChangedBase
{
    private string _timeStamp;

    public string TimeStamp
    {
        get { return _timeStamp; }
        set { SetProperty(value, ref _timeStamp); }
    }
}

If you want this to be really convenient, you can write a code snippet for this. This will be part of the snippet:

    <Snippet>
      <Declarations>
        <Literal>
          <ID>PropertyName</ID>
          <Type>String</Type>
          <ToolTip>The property name</ToolTip>
          <Default>NewProperty</Default>
        </Literal>
        <Literal>
          <ID>PropertyType</ID>
          <Type>
          </Type>
          <ToolTip>Replace with the type of the property</ToolTip>
          <Default>string</Default>
        </Literal>
        <Object>
          <ID>PrivateVariable</ID>
          <Type>Object</Type>
          <ToolTip>The name of the private variable</ToolTip>
          <Default>newPropertyValue</Default>
        </Object>
      </Declarations>
      <Code Language="csharp" Kind="method decl"><![CDATA[        private $PropertyType$ _$PrivateVariable$;
        public $PropertyType$ $PropertyName$
        {
            get { return _$PrivateVariable$; }
            set
            {
                SetProperty(value, ref _$PrivateVariable$);
            }
        }]]></Code>
    </Snippet>
0
source

Source: https://habr.com/ru/post/1615156/


All Articles