Косвенное уведомление о недвижимости - PullRequest
2 голосов
/ 20 апреля 2010

этот вопрос может выглядеть немного тривиальным, но это не так. Мне просто интересно, какой из следующих двух случаев лучше для косвенного уведомления собственности, или, возможно, есть еще лучший способ.

Сценарий:

У меня есть два свойства: первое - это объект с именем HoldingObject, второе - логическое значение с именем IsHoldingObject, которое имеет значение false, если HoldingObject == null, в противном случае оно равно true. Мне просто интересно, каков наилучший механизм уведомлений для IsHoldingObject:

Случай (A) - Уведомление IsHoldingObject изменено из свойства HoldingObject:

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
}

Случай (B) - Уведомить IsHoldingObject, измененный непосредственно из IsHoldingObject, установив для него значение false или true из свойства HoldingObject:

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
}

Лично я склоняюсь к первому, потому что для этого требуется меньше кода, но я не уверен, насколько это рекомендуется делать. Дайте мне знать, если есть другой (лучший) способ.

Спасибо!

Ответы [ 3 ]

1 голос
/ 20 апреля 2010

Я почти всегда иду на второй. Таким образом, весь код, отвечающий за установку данного свойства, находится в одном месте. В этом конкретном случае свойство IsHoldingObject полностью зависит от свойства HoldingObject, поэтому оно может не применяться. Но в целом, сейчас кода может быть меньше, но что произойдет, если позже вам потребуется обновить это свойство откуда-то еще?

Боль, которую вы испытываете (многословие кода), может быть легко уменьшена вспомогательным методом, который используется для установки свойств в модели представления (это может находиться в базовом классе):

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

    return false;
}

Ваши свойства становятся:

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 голос
/ 07 декабря 2010

В большинстве случаев это не имеет значения. Давайте посмотрим на варианты

  • Рассчитывать каждый раз. Итак, здесь вы потребляете процессор каждый раз, когда пользовательский интерфейс запрашивает значение. Но учитывая, сколько ЦП занимает каждый раз, когда пользовательский интерфейс должен запрашивать значение 100 с в секунду, прежде чем вы даже заметите попадание. Я сомневаюсь, что ваш интерфейс потребовал бы этого.
  • Сохраните значение. Здесь вы потребляете память. Опять же, это не проблема, если вы не храните много больших объектов.

Так что, я думаю, все сводится к тому, что для вас более читабельно Я предпочитаю «Расчет каждый раз». Затем, используя это http://code.google.com/p/notifypropertyweaver/, я могу написать этот код

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

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

    public event PropertyChangedEventHandler PropertyChanged;
}

И скомпилировать это в сборку (т.е. зависимость получена)

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); } }
}
0 голосов
/ 20 апреля 2010

интересная идея. Я думаю, я бы использовал подход BindingConverter, который преобразует HoldingObject в нужное вам значение.

Мне любопытны другие мнения.

Привет

...