wpf 将 Element 作为 CommandParameter 从 ElementTree 的根传递

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19052332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:44:45  来源:igfitidea点击:

Pass Element as CommandParameter from root of ElementTree

c#wpfxamldata-bindingmvvm

提问by Marschal

I searched a lot through Google and StackOverflow, but nothing answered my problem.

我通过 Google 和 StackOverflow 进行了大量搜索,但没有解决我的问题。

I have two Xaml Files:

我有两个 Xaml 文件:

MainWindow.xaml

主窗口.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. But if i try to reference the object by its name it fails...

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

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. I want to avoid using extra code in Code-behind.

那么我如何才能dockingManager从 xaml 中的 ElementTree 中找到并引用一个 Object ( )。我想避免在代码隐藏中使用额外的代码。

回答by Pawe? Motyl

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}"/>

回答by Davide Cannizzo

You can use:

您可以使用:

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

回答by meilke

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
  • The command will trigger a callback in the MainWindowViewModelinstance
  • This callback will change some state/properties in the MainWindowViewModelinstance
  • The DockingManagerinstance reacts to that adjusted state of the MainWindowViewModelinstance through bindings
  • 摆脱 CommandParameter
  • 该命令将在MainWindowViewModel实例中触发回调
  • 此回调将更改MainWindowViewModel实例中的某些状态/属性
  • 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. You are using elements of MVVM with Smart UI/Code Behind techniques.

你现在的做法太复杂了。除此之外,你在这里疯狂地混合模式。MVVM 尝试将业务逻辑与实际元素分离。您正在将 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 Windowthat is not possible.

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