[英]DataGridCheckBoxColumn does not update in MVVM when property is changed
[英]How to update UI change when property changed in MVVM
我正在尝试在WPF中完成正确的MVVM架构。
我有一个玩家,在“模型”部分有一个布尔属性,说明我们现在正在“玩”。
public bool IsPlaying
{
get
{
return isPlaying;
}
set
{
isPlaying = value;
OnPropertyChanged("IsPlaying");
}
}
(注意我实现了“INotifyPropertyChanged”接口,因此OnPropertyChanged
函数报告了更改)
在我的ViewModel中,我有一个名为“ToggleButtonIcon”的ImageSource属性:
public ImageSource ToggleButtonIcon
{
get
{
if (Model.IsPlaying)
return pauseIcon;
else
return playIcon;
}
}
我在视图中绑定到“TogglePlayButton”:
<cc:IconButton x:Name="TogglePlayButton"
Style="{StaticResource playButton}"
ImageSource="{Binding Path=ToggleButtonIcon,
UpdateSourceTrigger=PropertyChanged}"
Command="{Binding Path=TogglePlayCommand}"/>
(这是一个自定义控件,但它正在工作,我检查了)当然我希望按钮根据它是否正在播放(暂停)以及是否正在播放(播放)来更改其图像图标。
问题是ToggleButtonIcon
在更改时没有通知,我无法在ViewModel部分实现INotifyValueChanged
,因为a。 我明白这不是MVVM架构的一部分,而且b。 我不知道它何时发生变化,因为它取决于Model的IsPlaying
属性。
我想过将ToggleButtonIcon
属性放在Model部分,但那不是“业务逻辑”所以我认为这不是正确的方法。
我还想过使用转换器并将IconButton
直接绑定到“IsPlaying”,这可能会起作用,但我在这里读到: 如何在MVVM模式中使用WPF转换器? 你不应该在MVVM中使用转换器,因为你可以在“ViewModel”部分中进行任何你想要的转换。
在MVVM架构中实现这一目标的最佳方法是什么?
对我来说, IsPlaying
应该在ViewModel中,并且实现了更改通知,因为它代表了各种应用程序状态。
为了解决这个问题,我建议从ViewModel中取出ToggleButtonIcon
,并在IconButton
控件上创建一个DataTrigger
(通过它的Style
),它绑定到IsPlaying
属性(在ViewModel上)并根据它改变ImageSource
属性。
MVVM的模型应该只包含类实体,这些实体有时可以有一个INotiftPropertyChanged
,但通常它们不会。
你的意图是,它是传达一个状态,应该在你的viewmodel上。
我建议你将IsPlaying
的状态放在View Model(VM)上并绑定到它。 然后在TogglePlayCommand
的命令中,它将在VM上设置该属性。
这样两个项目都会在更改时更新属性。 您仍然可以在模型中创建原始对象,并在VM的IsPlaying
的Setter
上将类实例属性设置为其值(如果需要) 。
看看我的博客文章Xaml:ViewModel主页实例化和加载策略更容易绑定 。 请注意我如何使用OnPropertyChanged
在其他操作上推送更改消息,这些操作既可以实现您所寻求的灵活性,也可以使视图模型保持状态而不是模型。
你应该把bool放在实现接口INotifyPropertyChange的类上:这里有一个例子:
public class Game : INotifyPropertyChanged
{
private bool _isPlaying;
public string IsPlaying
{
get { return _isPlaying; }
set {
_isPlaying = value;
this.NotifyPropertyChangedBool();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChangedBool()
{
if (PropertyChanged != null)
{
PropertyChanged(this, new
PropertyChangedEventArgs("IsPlaying"));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.