将元素作为命令参数从 ElementTree 的根传递

本文关键字:ElementTree 参数 元素 命令 | 更新日期: 2023-09-27 18:33:06

我通过Google和StackOverflow搜索了很多,但没有一个能回答我的问题。

我有两个 Xaml 文件:

MainWindow.xaml

<Window x:Name="mainWindow">
    <Window.DataContext>
        <!-- Instantiate ViewModel of the MainWindow -->
        <vm:MainWindowViewModel x:Name="viewModel"/>
    </Window.DataContext>
    <!-- Create the Menu of the MainWindow -->
    <custom:MainMenu Grid.Row="0"/>
    <ad:DockingManager x:Name="dockingManager">
    <!-- ... -->
</Window>

MainMenu.xaml

<UserControl>
    <Menu>
        <MenuItem Header="{t:Translate MENU_LAYOUT_SAVE}" Command="{Binding SaveLayoutCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"/>
        <MenuItem Header="{t:Translate MENU_LAYOUT_LOAD}" Command="{Binding LoadLayoutCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"/>
    </Menu>
</UserControl>

这里我的问题发生了。我不想传递 Mainwindow-对象,而是想从 MainWindow 传递 DockingManager x:Name="dockingManager"。但是如果我尝试按对象名称引用对象,它会失败......

我尝试了以下绑定:

CommandParameter="{Binding ElementName=dockingManager}"
CommandParameter="{Binding ElementName=dockingManager, RelativeSource={RelativeSource AncestorType=Window}}"

那么我怎样才能从 xaml 中的元素树中找到和引用一个对象(dockingManager(。我想避免在代码隐藏中使用额外的代码。

将元素作为命令参数从 ElementTree 的根传递

尝试CommandParameter="{Binding ElementName=dockingManager, Path=.}" .

编辑:前面的答案行不通。这是一个工作思路...

在窗口中:

<custom:MainMenu Grid.Row="0" Tag="{Binding ElementName=dockingManager}" />

在 MainMenu.xaml 中:

<UserControl x:Name="UcMainMenu" />
...
    <MenuItem Header="{t:Translate MENU_LAYOUT_SAVE}" Command="{Binding SaveLayoutCommand}" CommandParameter="{Binding ElementName=UcMainMenu, Path=Tag}"/>

您可以使用:

CommandParameter="{x:Reference Name=yourElementName}"

由于您使用的是 MVVM,因此您应该做些什么来提出一个稍微不同的解决方案:

  • 摆脱CommandParameter
  • 该命令将在MainWindowViewModel实例中触发回调
  • 此回调将更改MainWindowViewModel实例中的某些状态/属性
  • DockingManager 实例通过绑定对MainWindowViewModel实例的调整状态做出反应

你现在的做法太复杂了。除此之外,您在这里疯狂地混合模式。MVVM 尝试将业务逻辑与实际元素分开。您正在使用具有智能 UI/代码隐藏技术的 MVVM 元素。

此外,请考虑对单个控件使用单个视图模型。主菜单控件是独立的,停靠管理器也是独立的。为什么?因为你想把所有东西都分解成更小的部分,但更重要的是,因为你可能有可重用性。主菜单尝试访问Window内的停靠管理器,这是不可能的。