我已经搜索并阅读了类似线程的负载以及观看了一些视频,但是我遇到了问题,我认为这归结为一些误解。我正在使用与UWP开发的MVVM进行70-357考试。
我的目标:在我的XAML页面中按下按钮,让它更改视图模式中对象的属性,然后在我的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--;
}
}
字符模型(切出许多无关的特性)
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;
}
}
- 我的所有属性似乎都正确找到了
- 当我单击按钮更改CurrentHP时,我看不到XAML上的反映
- 我知道 prism 和模板10 现有。我不想使用它们,因为我正在编写此代码来更好地理解这些事情以准备认证。将来,我可能会利用它们,但我试图弄清楚在这种情况下我在做错了什么。
到目前为止,我的理解是,我应该只在ViewModel上放置InotFyPropertychange,它可以处理警报,即自定义对象内部的任何属性(在这种情况下)发生了变化。
我错了吗?我是否需要在我的角色类上inotifyPropertychanged才能正确提醒XAML这些更改?
感谢此处的任何输入。
两件事可以防止您的UI更新:
- 您的
Character
无法实现 inotifyPropertychanged ,因此UI不会被告知更改。在适当的设置器中实现并调用 onPropertychanged ,否则您必须在myCharacter
上调用 onpropertychanged ,这应该刷新整个 targine ,但是第一个方法更好, - 第二重要的是,除非您使您绑定 Oneway -
x:Bind
是默认的 onetime ,否则它也无法正常工作,因此您应该更正:
<TextBlock Name="HPTB" Text="{x:Bind CharacterViewModel.myCharacter.CurrentHP, Mode="OneWay"}"...
在您的视图模型中,您已经实现了INotifyPropertyChanged
,因此,如果将Character
设置为新对象,则将执行事件,WPF将更新。
问题是,当Character
的属性更改时,未发送通知事件,WPF不知道刷新其值。
您可以在Character
中实现接口,在视图模型上启动INotifyPropertyChanged
,也可以将Character
的公共属性更改为依赖性属性。