MVVM 混淆试图让 INotifyProprerty 更改以使用 XAML 更新

MVVM confusion trying to get INotifyProprerty change to work with XAML updates

我搜索并阅读了大量类似的话题,还观看了一些视频,但我 运行 遇到了一些问题,我认为这归结为一些误解。我正在使用 MVVM 和 UWP 开发来学习 70-357 考试。

我的目标:在我的 XAML 页面中按下一个按钮,让它更改我的 ViewModel 中对象的 属性,然后将该值反映在我的 XAML 中的数据绑定中] 看法。

在我的项目中,我有以下内容:

主页XAML

<StackPanel Name="HPStack" Margin="0,0,10,0">
        <Button Name="HPIncrease" Click="{x:Bind CharacterViewModel.HPIncrease_Click}" Content="+" HorizontalAlignment="Center"/>
        <TextBlock Name="HPTB" Text="{x:Bind CharacterViewModel.myCharacter.CurrentHP}" Margin="0,0,5,0" HorizontalAlignment="Center"/> 
    <Button Name="HPDecrease" Click="{x:Bind CharacterViewModel.HPDecrease_Click}" Content="-" HorizontalAlignment="Center"/>
</StackPanel>

主页 C#

public CharacterDetailsViewModel CharacterViewModel;

public MainPage()
{
    this.InitializeComponent();
    CharacterViewModel = new CharacterDetailsViewModel();
}

角色视图模型(大部分代码来自我看到的解释

public class CharacterDetailsViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        //App data
        private Character _myCharacter;
        public Character myCharacter
        {
            set
            {
                _myCharacter = value;
                OnPropertyChanged();
            }
            get { return _myCharacter; }
        }

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

        //Constructors
        public CharacterDetailsViewModel()
        {
            _myCharacter = new Character(12, 12, 12, 12, 12, 12);
        }

        //buttons
        public void HPIncrease_Click(object sender, RoutedEventArgs e)
        {
            //TODO probably fix this
            myCharacter.CurrentHP++;
        }

        public void HPDecrease_Click(object sender, RoutedEventArgs e)
        {
            myCharacter.CurrentHP--;
        }

    }

Character Model(去掉了很多不相关的属性)

public class Character
{

    public int TotalHP { get; set; } //TODO not public
    public int CurrentHP {get;set;} //TODO check vs total HP and 0

//constructor for creating a new character with provided stats
public Character (int strength, int dexterity, int constitution, int intelligence, int wisdom, int charisma)
    {
        this.TotalHP = 50;
        this.CurrentHP = 45;
    }
}

到目前为止,我的理解是我应该只将 INotfyPropertyChanged 放在 ViewModel 上,它可以处理自定义对象(在本例中为 Character)内的任何 属性 已更改的警报。

我错了吗? 我的角色 class 是否需要 INotifyPropertyChanged 才能正确提醒 XAML 这些更改?

感谢您在这里提供任何意见。

在您的视图模型中,您已经实现了 INotifyPropertyChanged,因此如果您将 Character 设置为一个新对象,事件将被执行并且 WPF 将更新。

问题是当 Character 的 属性 改变时,没有发送通知事件,WPF 不知道刷新它的值。

您可以在 Character 中实现接口,在视图模型上触发 INotifyPropertyChanged,或者将 Character 的 public 属性更改为依赖属性.

有两件事会阻止您的 UI 更新:

  • 您的 Character 未实现 INotifyPropertyChanged,因此 UI 不会收到有关更改的通知。实现它并在适当的设置器中调用 OnPropertyChanged,否则你将不得不在 myCharacter 上调用 OnPropertyChanged,这应该会刷新整个 字符,但第一种方法更好,
  • 第二个重要的事情是它也不会工作,除非你让你绑定 OneWay - x:Bind 默认为 OneTime,所以你应该更正:
<TextBlock Name="HPTB" Text="{x:Bind CharacterViewModel.myCharacter.CurrentHP, Mode="OneWay"}"...