我的MVVM应用程序包含两个视图:
当用户在AllStrategiesView StrategyView中单击某个策略时,会创建此策略。我使用这样的代码来通知应用程序应该创建StrategyView:
.............
public void OpenStrategyView()
{
OnPropertyChanged("OpenStrategy");
}
.................
private void OnWorkspacePropertyChanged(object sender, PropertyChangedEventArgs e)
{
const string openStrategyString = "OpenStrategy";
if (e.PropertyName == openStrategyString)
{
AllStrategiesViewModel vm = (sender as AllStrategiesViewModel);
OpenStrategy(vm.SelectedStrategy);
}
}
然而程序的另一部分显示错误消息,因为没有这样的属性“OpenStrategy”:
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
问题是:
使用OnPropertyChanged
通知应用程序需要执行某些操作是对还是错?我应该重写我的代码以免使用OnPropertyChanged
还是禁用VerifyPropertyName
代码?
答案 0 :(得分:0)
这是不好的做法。 PropertyChanged
上的INotifyPropertyChanged
事件应该用于通知订阅者对象实例上的属性已更改。这通常在WPF中用于通知UI它需要使用新的属性值更新自己。
在MVVM中,您应该使用某种命令或替代视图模型/视图通信机制来从视图中调用视图模型上的动词(方法)。 WPF提供的命令有局限性,因此我建议使用MVVM framework及其提供的机制。
答案 1 :(得分:0)
这取决于你想要它做什么。在您的情况下,您看起来有一个属性“Workspace”,它指示您应该查看哪个VM。对于恕我直言,这似乎并不太糟糕。
如果你做了一些与被改变的属性完全无关的东西,那么它可能会起作用,但它肯定不是我期望它做的(见Principle of Least Astonishment)。 OnPropertyChanged旨在表明已绑定的属性已更改并应重新获取。
您当然可以在ViewModel上再举办一次活动,例如:
public event Action<String> OpenStrategy;
还有一件事......这段代码完全是多余的:
const string openStrategyString = "OpenStrategy";
if (e.PropertyName == openStrategyString)
从编译器的角度来看,以下内容完全相同,而且更具可读性:
if (e.PropertyName == "OpenStrategy")
答案 2 :(得分:0)
要求您的应用程序在PropertyChanged
事件中执行某些操作并没有错,但是不要仅仅为了请求应用程序执行某事而引发PropertyChanged
事件。
PropertyChanged
用于表示属性已更改,应仅用于此属性。
Devdigital's answer提供了一个很好的示例,即UI使用PropertyChange
通知来了解它应该何时更新。其他对象也可以订阅接收更改通知,并且只应在值更改时通知它们,而不是在您想要运行某些应用程序代码时通知。
使用你的例子,我会像这样重写它:
public void OpenStrategyView()
{
OpenStrategy(this.SelectedStrategy);
}
private void OnWorkspacePropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "SelectedStrategy")
{
OpenStrategyView();
}
}