简体   繁体   English

ViewModel和UserControl视图之间的通信

[英]Communication between ViewModel and UserControl's view

I working on WPF MVVM project. 我在WPF MVVM项目上工作。 I'm struggling with communication between viewmodel of my MainWindow and view of usercontrol , placed inside MainWindow . 我正在努力与我的MainWindow viewmodel和放置在MainWindowusercontrol视图之间的通信。

So I have: 所以我有:

  • UserControl 用户控件

  • MainWindow 主窗口

  • MainWindowViewModel MainWindowViewModel

My UserControl is very simple: 我的UserControl非常简单:

<Grid MouseDown="UIElement_OnMouseDown">
    <Rectangle Fill="BlueViolet" />
</Grid>

with code-behind (just rise an event when rectangle is clicked, and pass coordinates): 使用代码隐藏(只需在单击矩形时上升一个事件,并传递坐标):

public partial class FooUserControl : UserControl
{
    public FooUserControl()
    {
        InitializeComponent();
    }

    public event EventHandler<BarEventArgs> BarClick;
    private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        double x = e.GetPosition(this).X;
        double y = e.GetPosition(this).Y;
        string value_to_pass = "[" + x + "," + y + "]";

        BarEventArgs bar = new BarEventArgs() { Bar = 2, Foo = value_to_pass };
        BarClick?.Invoke(sender, bar);
    }
}

My MainWindow doesn't have code-behind. 我的MainWindow没有代码隐藏。 Just xaml. 只是xaml。 As you can see I pass click event via Command to MainWindowViewModel : 如您所见,我通过Command将Click事件传递给MainWindowViewModel

<Window.DataContext>
    <viewModels:MainWindowViewModel />
</Window.DataContext>
<Grid>
    <local:FooUserControl>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="BarClick">
                <cmd:EventToCommand Command="{Binding ClickedCommand}" PassEventArgsToCommand="True" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </local:FooUserControl>
</Grid>

and finally my MainWindowViewModel has just this command: 最后我的MainWindowViewModel只有这个命令:

public class MainWindowViewModel : ObservableObject
{
    public ICommand ClickedCommand => new RelayCommand<BarEventArgs>(o => Clicked(o.Foo));
    private void Clicked(string a)
    {
        Debug.WriteLine("Clicked " + a);
    }
}

So, communication from UserControl's view to MainWindow's viewmodel, via command, works great. 因此,从UserControl的视图到MainWindow的viewmodel(通过命令)的通信效果很好。 But, how can I communicate in opposite way? 但是, 我怎么能以相反的方式沟通? From MainWindowViewModel to UserControl's view? 从MainWindowViewModel到UserControl的视图?

Your ViewModels should not access your Views directly. 您的ViewModel不应直接访问您的视图。 They should not care about Views at all. 他们根本不应该关心意见。 All they do, is, provide properties to make data available. 他们所做的就是提供使数据可用的属性。 Views can now bind to these properties. 视图现在可以绑定到这些属性。

So, all communication from the ViewModel to the View works through Bindings only. 因此,从ViewModel到View的所有通信仅通过Bindings工作。 When the ViewModel has to tell the View something, it provides a property. 当ViewModel必须告诉View某事时,它提供了一个属性。 Then it's up to the View to bind to that property and do something with it - whatever this might be. 然后由View决定绑定到该属性并对其执行某些操作 - 无论这可能是什么。

MVVM says,view should talk only to its viewmodel and viewmodels can talk to other viewmodels only(and model). MVVM说,视图应该只与它的viewmodel对话,viewmodel只能与其他视图模型(和模型)对话。
What you need is a Mediator. 你需要的是一个调解员。 在此输入图像描述
Source : http://dotnetpattern.com/mvvm-light-messenger/ 资料来源: http//dotnetpattern.com/mvvm-light-messenger/
With this you don't have to create event in your usercontrol.you can communicate to any viewmodel that is instantiated. 有了这个,您不必在usercontrol中创建事件。您可以与任何实例化的视图模型进行通信。 You can use mvvm-light,which provides an implementation of Mediator pattern(Messenger).it also provides other tools that will help you build MVVM application. 您可以使用mvvm-light,它提供了Mediator模式(Messenger)的实现。还提供了其他工具来帮助您构建MVVM应用程序。
here is a tutorial to MVVMLight Messenger. 是MVVMLight Messenger的教程。

With binding you can update the view appropriately. 通过绑定,您可以适当地更新视图。
thus viewmodels talk to each other and views are updated by corresponding view. 因此,视图模型相互通信,视图由相应的视图更新。
this way you wont be violating any MVVM principle. 这样你就不会违反任何MVVM原则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM