简体   繁体   English

从ElementTree的根传递元素作为CommandParameter

[英]Pass Element as CommandParameter from root of ElementTree

I searched a lot through Google and StackOverflow, but nothing answered my problem. 我通过Google和StackOverflow进行了大量搜索,但没有回答我的问题。

I have two Xaml Files: 我有两个Xaml文件:

MainWindow.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>

And the MainMenu.xaml 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>

And here my Problem occurs. 在这里我的问题出现了。 Instead of passing the Mainwindow-object I want to pass the DockingManager x:Name="dockingManager" from MainWindow. 我想从MainWindow传递DockingManager x:Name="dockingManager" ,而不是传递Mainwindow对象。 But if i try to reference the object by its name it fails... 但是,如果我尝试通过其名称引用该对象,它将失败...

I tried the following Bindings: 我尝试了以下绑定:

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

So how can I find and reference an Object ( dockingManager ) from the ElementTree within xaml. 那么如何从xaml中的ElementTree中找到并引用一个Object( dockingManager )。 I want to avoid using extra code in Code-behind. 我想避免在代码隐藏中使用额外的代码。

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

EDIT: The previous answer would not work. 编辑:以前的答案是行不通的。 Here's a working idea... 这是一个有用的想法......

In the Window.xaml: 在Window.xaml中:

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

In the MainMenu.xaml: 在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}"

Since you are using MVVM here is what you should do to come up with a slightly different solution: 既然你正在使用MVVM,那么你应该做些什么来提出一个稍微不同的解决方案:

  • Get rid of the CommandParameter 摆脱CommandParameter
  • The command will trigger a callback in the MainWindowViewModel instance 该命令将在MainWindowViewModel实例中触发回调
  • This callback will change some state/properties in the MainWindowViewModel instance 此回调将更改MainWindowViewModel实例中的某些状态/属性
  • The DockingManager instance reacts to that adjusted state of the MainWindowViewModel instance through bindings DockingManager实例通过绑定对MainWindowViewModel实例的调整状态做出反应

The way you are doing it now is way too complicated. 你现在这样做的方式太复杂了。 In addition to that, you are wildly mixing patterns here. 除此之外,你在这里疯狂地混合模式。 MVVM tries to separate the business logic from the actual elements. MVVM尝试将业务逻辑与实际元素分开。 You are using elements of MVVM with Smart UI/Code Behind techniques. 您正在使用MVVM的元素与智能UI /代码隐藏技术。

Also, consider using individual view models for individual controls. 另外,请考虑为各个控件使用单独的视图模型。 The main menu control is separate and the docking manager is, too. 主菜单控件是独立的,对接管理器也是。 Why? 为什么? Because you want to break everything into smaller pieces, but more importantly, because you might have reusability in mind. 因为您希望将所有内容分解为更小的部分,但更重要的是,因为您可能会考虑到可重用性。 With the main menu trying to access a docking manager inside a Window that is not possible. 主菜单尝试访问Window内的对接管理器,这是不可能的。

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

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