ViewModel和UserControl视图之间的通信

时间:2016-02-16 18:11:41

标签: c# .net wpf xaml mvvm

我正在研究WPF MVVM项目。我在MainWindow的视图模型与usercontrol的视图之间进行通信,并置于MainWindow内。

所以我有:

  • 用户控件

  • 主窗口

  • MainWindowViewModel

我的 UserControl 非常简单:

<Grid MouseDown="UIElement_OnMouseDown">
    <Rectangle Fill="BlueViolet" />
</Grid>
带代码隐藏的

(单击矩形时只上升一个事件,并传递坐标):

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);
    }
}

我的 MainWindow 没有代码隐藏功能。只是xaml。如您所见,我将Click事件通过Command传递给 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>

最后我的 MainWindowViewModel 只有这个命令:

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

因此,通过命令从UserControl的视图到MainWindow的viewmodel的通信效果很好。但是,我怎么能以相反的方式沟通?从MainWindowViewModel到UserControl的视图?

2 个答案:

答案 0 :(得分:3)

您的ViewModel不应直接访问您的视图。他们根本不应该关心意见。他们所做的就是提供使数据可用的属性。视图现在可以绑定到这些属性。

因此,从ViewModel到View的所有通信都只通过Bindings工作。当ViewModel必须告诉View某事时,它提供了一个属性。然后它可以通过View来绑定到该属性并对其执行某些操作 - 无论这可能是什么。

答案 1 :(得分:2)

MVVM说,视图应该只与它的viewmodel对话,而viewmodel只能与其他视图模型(和模型)交谈。
你需要的是一个调解员。 enter image description here来源:http://dotnetpattern.com/mvvm-light-messenger/
有了这个,您不必在usercontrol中创建事件。您可以与任何实例化的视图模型进行通信。 您可以使用mvvm-light,它提供了Mediator模式(Messenger)的实现。还提供了其他工具来帮助您构建MVVM应用程序。
here是MVVMLight Messenger的教程
通过绑定,您可以适当地更新视图 因此视图模型相互通信,视图通过相应的视图更新。这样你就不会违反任何MVVM原则。