Indirect Ownership Notice

this question may look a little trivial, but it may not. I'm just wondering which of the following two cases is better for indirect property notification, or maybe there is an even better way.

Scenario:

I have two properties, the first is an object named HoldingObject, the second is a boolean called IsHoldingObject, which is false if HoldObject == null, otherwise it is true. I'm just wondering what is the best notification mechanism for IsHoldingObject:

Case (A) - Modify the IsHoldingObject from the HoldingObject proxy:

public class NotifyingClass1 : INotifyPropertyChanged
{
    private object _holdingObject;
    public object HoldingObject
    {
        get { return _holdingObject; }
        set
        {
            if (_holdingObject != value)
            {
                _holdingObject = value;
                NotifyPropertyChanged("HoldingObject");
                // Notify from the property that is being checked
                NotifyPropertyChanged("IsHoldingObject");
            }
        }
    }

    public bool IsHoldingObject { get { return this.HoldingObject == null; } }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

      

Case (B) - Notify about IsHoldingObject directly from IsHoldingObject by setting it to false or true from the HoldingObject property:

public class NotifyingClass2 : INotifyPropertyChanged
{
    private object _holdingObject;
    public object HoldingObject
    {
        get { return _holdingObject; }
        set
        {
            if (_holdingObject != value)
            {
                _holdingObject = value;
                NotifyPropertyChanged("HoldingObject");

                // 1) Set the property here
                this.IsHoldingObject = _holdingObject != null;
            }
        }
    }

    private bool _isHoldingObject;
    public bool IsHoldingObject
    {
        get { return _isHoldingObject; }
        set
        {
            if (_isHoldingObject != value)
            {
                _isHoldingObject = value;

                // 2) Notify directly from the property
                NotifyPropertyChanged("IsHoldingObject");
            }
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

      

I personally lean towards the former because it requires less code, but I'm not sure how much of a recommendation it is. Let me know if there is another (better) way.

Thanks!

+2


a source to share


3 answers


I almost always go for the second one. Thus, all the code responsible for setting this property is in one place. In this particular case, the IsHoldingObject property depends entirely on the HoldingObject property, so it may not apply. But overall it might be less code, but what happens if you need to update this property from somewhere else later?

The pain you are experiencing (code verbosity) can be easily mitigated by a helper method that is used to set properties on the view model (this can live in the base class):

protected bool SetValue<T>(ref T field, T value, string propertyName)
{
    if (!Equals(field, value))
    {
        field = value;
        NotifyPropertyChanged(propertyName);
        return true;
    }

    return false;
}

      



Then your properties become:

private object _holdingObject;
public object HoldingObject
{
    get { return _holdingObject; }
    set
    {
        if (SetValue(ref _holdingObject, value, "HoldingObject"))            
            this.IsHoldingObject = _holdingObject != null;
    }
}

private bool _isHoldingObject;
public bool IsHoldingObject
{
    get { return _isHoldingObject; }
    private set { SetValue(ref _isHoldingObject, value, "IsHoldingObject"); }
}

      

+1


a source


In most scenarios, this is irrelevant. Let's take a look at the options

  • Calculate every time. So here you are consuming CPU every time the UI asks for a value. But considering how much CPU it takes every time the UI has to ask for a value of 100 seconds per second, before you even notice a hit. I doubt your interface will require this.
  • Save the value. This is where you consume memory. Again, this is not a problem unless you store many large objects.

So, I guess it comes down to what is ever more readable for you. I prefer "Calculate every time". Then using http://code.google.com/p/notifypropertyweaver/ I can write this code



public class NotifyingClass1 : INotifyPropertyChanged
{
    public object HoldingObject { get; set; }

    public bool IsHoldingObject { get { return HoldingObject == null; } }

    public event PropertyChangedEventHandler PropertyChanged;
}

      

And compile it to build (i.e. got dependency)

public class NotifyingClass1 : INotifyPropertyChanged
{
    private object holdingObject;

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public object HoldingObject
    {
        get { return holdingObject; }
        set
        {
            if (holdingObject !=value)
            {
                holdingObject = value;
                OnPropertyChanged("HoldingObject");
                OnPropertyChanged("IsHoldingObject");
            }
        }
    }

    public bool IsHoldingObject { get { return (HoldingObject == null); } }
}

      

+1


a source


interesting idea. I think I would use the BindingConverter approach which converts the HoldObject to the value you want.

I am interested to know other opinions.

Hello

0


a source







All Articles