将UserControl命令绑定到MainWindow WPF / MVVM

时间:2018-02-02 13:39:50

标签: c# wpf mvvm user-controls

我有一个UserControl,它只是一个简单的DataGrid来展示一些东西,它有自己的ViewModel和Model。

我想每当我点击DataGrid时,都会举起一个事件。到目前为止,它正在使用命令,我在UserControl.ViewModel上获取事件。

问题是我需要在MainWindow.ViewModel中引发事件,它包含加载UserControl.DataGrid中所需内容的逻辑。

我对WPF和MVVM的理解很少,我有以下几种选择:

  • UserControl.DataGridClicked的DependencyProperty(我想避免,并尽可能坚持MVVM)
  • 将MainWindow.ViewModel实例提供给UserControl.ViewModel的构造函数,以便我可以直接引发事件。
  • 创建一个BusinessLogic类,并将逻辑放在那里,这样我就可以在UserControl.ViewModel或MainWindow.ViewModel上调用它。

这就是我调用UserControl的方式:

<Window>
    <Grid>
        <TabControl>
            <TabItem Header="{Binding Model.TabImportHeader}">
                <views:ResultView DataContext="{Binding ResultViewModel}"/>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

这是我的UserControl:

<UserControl x:Class="ResultView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:viewModels="clr-namespace:ViewModels"
             mc:Ignorable="d"
             d:DataContext="{d:DesignInstance Type=viewModels:ResultViewModel, IsDesignTimeCreatable=False}">

    <!--DataGrid-->
    <DataGrid ItemsSource="{Binding Model.ObservableCollection}"
              ColumnWidth="*"
              AutoGenerateColumns="false"
              IsReadOnly="True"
              BorderThickness="0"
              Background="White"
              HeadersVisibility="Column">

        <!--InputBindings-->
        <DataGrid.InputBindings>
            <MouseBinding Gesture="LeftClick"
                          Command="{Binding LeftClickCommand}">

            </MouseBinding>
        </DataGrid.InputBindings>
        <!--InputBindings-->

        <DataGrid.Columns>
            <DataGridTextColumn Header="Filename"
                                Binding="{Binding FileInfo.Name}"
                                Width="Auto" />
        </DataGrid.Columns>
    </DataGrid>
</UserControl>

任何WPF大师谁也对良好做法有所了解?我真的很感激任何帮助。

提前致谢。

编辑:命令声明:

public ICommand = new RelayCommand(LeftClick, () => true);

1 个答案:

答案 0 :(得分:1)

您可以使用MainWindowViewModel

直接绑定到{RelativeSource}中的命令
<MouseBinding Gesture="LeftClick" Command="{Binding DataContext.CommandPropertyInMainWindowVm, RelativeSource={RelativeSource AncestorType=Window}}" />

或者您可以绑定到使用事件聚合器或消息总线发布事件的UserControlViewModel命令。然后MainWindowViewModel将订阅此活动。有关详细信息,请参阅以下博客文章:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

使用事件聚合器在两个组件(例如两个视图模型)之间进行通信,可以消除发布者与事件订阅者之间的紧密耦合。两个视图模型都引用了事件聚合器,但它们不必彼此有任何关系。当在MVVM中以松散耦合的方式在视图模型之间进行通信时,这是最佳实践。

您需要一个事件聚合器实现。大多数MVVM库都包含一个。在Prism中,该类称为EventAggregator。在Mvvm Light中,它被称为Messengerhttps://marcominerva.wordpress.com/2014/06/25/how-to-send-string-and-content-messages-with-mvvm-light-messenger/。但这个概念是一样的。