MVVM问题。 ViewModel和View之间的消息传递,如何最好地实现?
应用程序有一些“用户通信”点,例如:“您已为此选择输入了注释。当“是/否/ NA”选择的值发生变化时,您是希望保存还是“丢弃”。 所以我需要一些被禁止的View绑定到ViewModel的“消息”的方式。
我从MVVM Foundation的Messenger开始走下去。然而,这更像是系统范围的广播,而不是事件/订户模型。因此,如果应用程序有两个View实例(Person1 EditView和Person2 EditView)打开,当一个ViewModel发布“你想保存”消息时,它们都会收到消息。
你用过什么方法?
由于 安迪
答案 0 :(得分:5)
对于所有这些,您将使用绑定作为“通信”的方法。例如,可能会根据ViewModel中设置的属性显示或隐藏确认消息。
这是视图
<Window.Resources>
<BoolToVisibilityConverter x:key="boolToVis" />
</Window.Resources>
<Grid>
<TextBox Text="{Binding Comment, Mode=TwoWay}" />
<TextBlock Visibility="{Binding IsCommentConfirmationShown,
Converter={StaticResource boolToVis}"
Text="Are you sure you want to cancel?" />
<Button Command="CancelCommand" Text="{Binding CancelButtonText}" />
</Grid>
这是你的ViewModel
// for some base ViewModel you've created that implements INotifyPropertyChanged
public MyViewModel : ViewModel
{
//All props trigger property changed notification
//I've ommited the code for doing so for brevity
public string Comment { ... }
public string CancelButtonText { ... }
public bool IsCommentConfirmationShown { ... }
public RelayCommand CancelCommand { ... }
public MyViewModel()
{
CancelButtonText = "Cancel";
IsCommentConfirmationShown = false;
CancelCommand = new RelayCommand(Cancel);
}
public void Cancel()
{
if(Comment != null && !IsCommentConfirmationShown)
{
IsCommentConfirmationShown = true;
CancelButtonText = "Yes";
}
else
{
//perform cancel
}
}
}
这不是一个完整的示例(唯一的选择是肯定!:)),但希望这说明您的View和ViewModel几乎是一个实体,而不是两个互相打电话的实体。
希望这有帮助。
答案 1 :(得分:2)
Anderson描述的内容可能足以满足您描述的特定要求。但是,您可能需要查看 Expression Blend Behaviors ,它为视图模型和视图之间的交互提供了强大的支持,这在更复杂的场景中可能很有用 - 使用'messages'绑定只会让你如此远。
注意,表达式混合SDK是免费提供的 - 您不必使用Expression Blend来使用SDK或行为;虽然Blend IDE确实有更好的内置支持来“拖放”行为。
另外,请注意每个'行为'是一个组件 - 换句话说,它是一个可扩展的模型; SDK中有一些内置行为,但您可以编写自己的行为。
以下是一些链接。 (注意,不要让URL中的'silverlight'误导你 - WPF和Silverlight都支持这些行为):