Элементы представления с привязкой к данным все еще не обновляются, несмотря на использование пакета Fody PropertyChanged в приложении Windows Phone 8?

У меня есть приложение C# Windows Phone 8 MVVM с установленным пакетом Fody PropertyChanged. Я добавил директиву ImplementPropertyChanged перед объявлением класса:

[CompilerGenerated]
[GeneratedCode("Radarc", "4.0")]
[ImplementPropertyChanged]
public partial class MilitaryRobots_VideosViewModel : ViewModelsBase.VMBase, IViewModels.IMilitaryRobots_VideosViewModel, INotifyPropertyChanged

У меня есть два следующих свойства в классе, к которым я привязываю элементы View:

    private Visibility _showDetailsVideo = Visibility.Collapsed;

    public Visibility ShowDetailsVideo 
    { 
        get
        {
            return this._showDetailsVideo;
        }

        set
        {
            this._showDetailsVideo = value;
            this.ShowMainScreen = value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
        }
    }

    private Visibility _showMainScreen = Visibility.Visible;

    /// <summary>
    /// Never set this property, instead set ShowDetailsVideo instead.
    /// </summary>
    public Visibility ShowMainScreen
    {
        get
        {
            return this._showMainScreen;
        }

        private set
        {
            this._showMainScreen = value;
        }
    }

Свойство Visibility одного элемента View связано со свойством ShowDetailsVideo модели представления. Свойство Visibility другого элемента View связано со свойством ShowMainScreen модели представления. Во время выполнения к обоим получателям свойств обращаются, указывая, что пара связанных элементов View обращается к свойствам по крайней мере один раз. Кроме того, два элемента View имеют правильные состояния видимости. Однако, если я изменяю свойство ShowDetailsVideo во время выполнения, доступ к установщикам осуществляется, но не к получателям, что указывает на то, что проводка между свойствами и свойствами элемента представления не работает, несмотря на мое использование пакета Fody PropetyChanged. Поведение доступа к свойствам такое же, как если бы пакет Fody даже не существовал.

Как я могу это исправить и заставить его работать, чтобы пара элементов вида свойств Visibility корректно обновлялась во время выполнения? Я думал, что пакет Fody PropertyChanged должен был сделать ненужным уведомление об изменении свойства реализации.

1 ответ

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

Ниже приведен исправленный код View Model для корректной работы уведомлений об измененных свойствах. Представление не обновлялось, когда привязываемые свойства в модели представления были изменены, потому что я не вызывал базовый метод SetProperty() в установщике свойств, вместо этого я выполнял только прямое назначение, чтобы уведомление об изменении свойства не вызывалось. Вы можете видеть это в установщике свойств в моем оригинальном сообщении. Простое добавление вызова SetProperty() исправило все.

Поэтому, если ваш класс View Model происходит от класса, подобного BindableBase (см. Ниже), вам вообще не нужен плагин Fody PropertyChanged, но убедитесь, что вы вызываете SetProperty() в своих установщиках свойств, а не делаете прямое присвоение данным член, поддерживающий собственность.

Обновлены установщики / получатели свойств

    private Visibility _showDetailsVideo = Visibility.Collapsed;

    public Visibility ShowDetailsVideo 
    { 
        get
        {
            return this._showDetailsVideo;
        }

        set
        {
            SetProperty(ref this._showDetailsVideo, value);
            this.ShowMainScreen = value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
        }
    }

    private Visibility _showMainScreen = Visibility.Visible;

    /// <summary>
    /// Never set this property, instead set ShowDetailsVideo instead.
    /// </summary>
    public Visibility ShowMainScreen
    {
        get
        {
            return this._showMainScreen;
        }

        private set
        {
            SetProperty(ref this._showMainScreen, value);
        }
    }

Класс BindableBase, с которого произошла моя модель представления

/// <summary>
/// Abstraction of data-binder that notifies properties changes to the suitable View.
/// </summary>
public abstract class BindableBase : INotifyPropertyChanged
{
    /// <summary>
    /// Event launched when a property of the bindable object has changed.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Sets the value of the binded property.
    /// </summary>
    /// <typeparam name="T">The generic type.</typeparam>
    /// <param name="storage">The type of the property.</param>
    /// <param name="value">The value of the property.</param>
    /// <param name="propertyName">The name of the property.</param>
    /// <returns>A boolean indicating the success of the assignation.</returns>
    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName]String propertyName = null)
    {
        if (Equals(storage, value)) return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    /// <summary>
    /// Event handler for the PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The name of the property that has changed.</param>
    protected void OnPropertyChanged(string propertyName = null)
    {
        //if (Debugger.IsAttached)
        //    Debug.WriteLine("Property changed: " + propertyName);

        var eventHandler = PropertyChanged;
        if (eventHandler != null)
            eventHandler(this, new PropertyChangedEventArgs(propertyName));
    }

    /// <summary>
    /// Initializes the bindable object.
    /// </summary>
    /// <param name="parameters">Dictionary with the parameters.</param>
    public virtual void Initialize(IDictionary<string, string> parameters)
    {

    }
}
Другие вопросы по тегам