将 UserControl 命令绑定到 MainWindow WPF/MVVM

Binding UserControl Command to MainWindow WPF/MVVM

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

我想在每次单击 DataGrid 时引发一个事件。到目前为止,它正在使用命令,我在 UserControl.ViewModel.

上收到了事件

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

以我对WPF和MVVM的一点了解,我有以下选择:

这就是我调用 UserControl 的方式:

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

这是我的用户控件:

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

您可以使用 {RelativeSource}:

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

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

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

您将需要一个事件聚合器实现。大多数 MVVM 库都包含一个。在 Prism the class is called EventAggregator. In Mvvm Light it's called Messenger: https://marcominerva.wordpress.com/2014/06/25/how-to-send-string-and-content-messages-with-mvvm-light-messenger/。不过概念是一样的。