gpt4 book ai didi

WPF 菜单项.CommandTarget

转载 作者:行者123 更新时间:2023-12-02 15:17:43 24 4
gpt4 key购买 nike

有人知道 MenuItem 上的 CommandTarget 属性可以用来做什么吗? The documentation says the following :

When used with a RoutedCommand, the command target is the object on which the Executed and CanExecute events are raised. If the CommandTarget property is not set, the element with keyboard focus will be used as the target.

但是,在运行时,CommandTarget 的值在命令的执行处理程序中看不到。 sender 是 CommandBinding 所属的窗口。 ExecutedRoatedEventArgs 充满了对菜单项的远祖的引用。

这里的目标是实现一个命令,该命令可以从各种不同网格、列表等上的各种不同上下文菜单执行 - 它们都包含支持特定界面的项目。它们的上下文菜单有所不同,但有一些共同的命令。无论您单击什么,通用命令都使用相同的 Executed 和 CanExecute 处理程序,因为“Foo”命令执行“Foo”操作。处理程序找出您单击的任何网格/列表的选定项目是什么,尝试将其转换为接口(interface),并在具有该接口(interface)的情况下对其执行某些操作(如果给定命令使用的接口(interface)不受该项目,该命令被禁用)。如果我将 ContextMenu 或 MenuItem 作为发送者,我可以获得 PlacementTarget 并且我知道用户单击的内容,但这只有在我在 ContextMenu 的 XAML 定义中定义 CommandBinding 时才有效 - 这意味着复制并粘贴该内容使用该命令的每个 ContextMenu 中的整个 XAML block ,并在每个 View 类中重新定义处理程序。这不是我想要维持的困惑。

在这种情况下,没有任何与语言无关的原因可以多次编写这些处理程序,或者将每个处理程序与给定命令多次关联。但据我所知,XAML 似乎希望您将处理程序和目标全部绑定(bind)在一起。您可以绑定(bind)处理程序一次,然后潜入不同的目标吗?

更新:我通过将命令放入静态 Command 类中,将处理程序放入非静态类(主视图,并不重要)中,并编写实例化的静态 Command.GetCommandBinding(command) 方法来解决此问题并为您传入的命令返回 CommandBinding。因此,如果我想在网格 Bar 上使用命令 Foo,则在 Bar 所在 View 的构造函数中,我只需调用以下命令:

Bar.CommandBindings.Add(Commands.GetCommandBinding(Commands.Foo));

当 Bar 被分配给属于 Bar 的 ContextMenu 的 MenuItem 的 Command 属性时,Bar 将作为命令上 Executed 和 CanExecute 事件的发送者进行传递。

无法在 XAML 中进行绑定(bind),因为处理程序必须是 View 类的成员。奇怪的是,设计者投入了如此多的工作来帮助我们重用命令的名称,同时使重用实际的命令(例如命令的代码)变得如此痛苦,但无论如何。这并不是 Microsoft 做过的最愚蠢的事情,而且 XAML 的其余大部分都非常棒(恕我直言)。

另一个解决方案:将菜单项定义为独立于上下文菜单的资源,并重用整个菜单项。它位于 Resources.xaml 中,我可以将其作为合并字典包含在其他 XAML 文件中。事件处理程序位于 Resources.cs 中。消费者可以使用 GridContextMenu,或者以相同的方式将 CtxMenuItem_EmailDocument 插入到自己的上下文菜单中。

<MenuItem Command="{x:Static vw:Commands.EmailDocument}" 
x:Key="CtxMenuItem_EmailDocument">
<MenuItem.CommandBindings>
<CommandBinding Command="{x:Static vw:Commands.EmailDocument}"
Executed="EmailDocument_Executed"
CanExecute="EmailDocument_CanExecute"
/>
</MenuItem.CommandBindings>
</MenuItem>

<ContextMenu x:Key="GridContextMenu" x:Shared="true">
<!-- other items -->
<StaticResource ResourceKey="CtxMenuItem_EmailDocument" />
<!-- other items -->
</ContextMenu>

CommandTarget 似乎在按钮上表现出完全不同的行为。或者,如果 CommandBindings 是在单独的文件中定义的,或者作为资源,或者......其他什么,则 CommandBindings 的行为完全不同。

最佳答案

AndrewS 编写的所有内容都是正确的,我只是想补充一点,CommandTarget 将是 Executed/CanExecute 事件的发送者。为了能够处理该命令,CommandTarget 需要相关命令的 CommandBinding。

最小示例:

<StackPanel>
<Button Command="Open" CommandTarget="{Binding ElementName=TestTextBox}">Open</Button>
<TextBox x:Name="TestTextBox">
<TextBox.CommandBindings>
<CommandBinding Command="Open" Executed="CommandBinding_Executed"/>
</TextBox.CommandBindings>
</TextBox>
</StackPanel>

关于WPF 菜单项.CommandTarget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17068055/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com