MVVM ViewModel 查看消息传递

发布于 2024-08-16 12:58:24 字数 370 浏览 5 评论 0原文

MVVM 问题。 ViewModel 和 View 之间的消息传递,如何最好地实现?

该应用程序有一些“用户通信”要点,例如:“您已为此选择输入了评论。当“是”/“否”/“不适用”选项的值发生变化时,“您希望保存还是放弃”。 所以我需要一些禁止的方式将 View 绑定到 ViewModel 的“消息”。

我从 MVVM Foundation 的 Messenger 开始走上这条路。然而,这更多的是系统范围的广播,而不是事件/订阅者模型。因此,如果应用程序打开了两个视图实例(Person1 EditView 和 Person2 EditView),那么当一个 ViewModel 发布“您要保存吗”消息时,它们都会收到消息。

你用了什么方法?

谢谢 安迪

MVVM question.
Messaging between ViewModel and View, how is it best implemented?

The application has some points of “user communication” such as: “You have entered comments for this selection. Do you wish to save or discard” when the value of a Yes/No/NA selection changes.
So I need some proscribed way of the View binding to the ViewModel’s “messages” .

I went down path starting with MVVM Foundation's Messenger. However that is more of a system-wide broadcast then a event/subscriber model. So, if the app has two instances of a View (Person1 EditView and Person2 EditView) open they both get the message when one ViewModel publishes the "do you want to save" message.

What approach have you used?

Thanks
Andy

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷港 2024-08-23 12:58:24

对于所有这些,您将使用绑定作为“通信”的方法。例如,确认消息可能会根据 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
          }
     }
}

这不是完整的示例(唯一的选项是 yes!:)),但希望这说明您的 View 和 ViewModel 几乎是一个实体,而不是两个互相打电话的实体。

希望这有帮助。

For all of this you would use binding as your method for "communication". For example, the confirmation message might be shown or hidden based on properties set in your ViewModel.

Here's the View

<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>

And here is your 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
          }
     }
}

This is not a full sample (the only option is yes! :) ), but hopefully this illustrates that your View and your ViewModel are almost one entity and not two that are making phone calls to each other.

Hope this helps.

撧情箌佬 2024-08-23 12:58:24

安德森所描述的内容可能足以满足您所描述的特定要求。但是,您可能需要研究表达式混合行为,它为视图模型和视图之间的交互提供强大的支持,这在更复杂的场景中可能很有用 - 使用“消息”绑定只会让您如此远的。

请注意,表达式混合 SDK 是免费提供的 - 您不必使用 Expression Blend 来使用 SDK 或行为;尽管 Blend IDE 确实对“拖放”行为有更好的内置支持。

另外,请注意每个“行为”都是一个组件 - 换句话说,它是一个可扩展的模型; SDK 中有一些内置行为,但您可以编写自己的行为。

这里有一些链接。 (请注意,不要让 URL 中的“silverlight”误导您 - WPF 和 Silverlight 均支持这些行为):

信息

Blend SDK

有关行为的视频

What Anderson describes is probably sufficient for the particular requirement you describe. However, you may want to look into Expression Blend Behaviors which provide powerful support for interactions between view models and views, which may be useful in more complex scenarios - using binding for 'messages' will only get you so far.

Note, the expression blend SDK is freely available - you don't have to use Expression Blend to use the SDK or the behavior; although the Blend IDE does have better inbuilt support for 'drag and drop' of behaviors.

Also, note each 'behavior' is a component - in other word it's an extensible model; there are a few built-in behaviors in the SDK, but you can write your own behaviors.

Here are some links. (Note, don't let the 'silverlight' in the URL mislead you - behaviors are supported for both WPF and Silverlight):

information

Blend SDK

video on behaviors

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文