0

我已经构建了一个 UserControl,其中包含许多包含 TextBlock 控件的边框。TextBlocks 的 Text 属性设置为来自我的 ViewModel 对象的数据。

我在 UserControl 的资源中添加了几个上下文菜单:

<UserControl.Resources>
    <ContextMenu x:Key="ContextMenu">
        <MenuItem Header="Copy Plate"   Command="cs:CarSystemCommands.CopyPlateCommand" />
        <MenuItem Header="Search Plate" Command="cs:CarSystemCommands.SearchPlateCommand" />
    </ContextMenu>
    <ContextMenu x:Key="TextBoxContextMenu">
        <MenuItem Header="_Copy"        Command="Copy" />
        <MenuItem Header="Copy Plate"   Command="cs:CarSystemCommands.CopyPlateCommand" />
        <MenuItem Header="Search Plate" Command="cs:CarSystemCommands.SearchPlateCommand" />
    </ContextMenu>
</UserControl.Resources>

我在我的 TextBlocks 中添加了对上下文菜单的引用。这是一个例子:

<Border Background="#FFFFFF78" 
        BorderBrush="Black" 
        BorderThickness="2" 
        ContextMenu="{StaticResource TextBoxContextMenu}"
        Grid.Column="0" 
        Margin="5,10,5,5">
    <TextBlock FontSize="18" 
               FontWeight="Bold"
               HorizontalAlignment="Center" 
               Margin="5" 
               x:Name="Camera" 
               VerticalAlignment="Center" />
</Border>

最后,我在 UserControl 中添加了 CommbandBindings:

<UserControl.CommandBindings>
    <CommandBinding Command="Copy"                                  CanExecute="CopyCommand_CanExecute" Executed="CopyCommand_Executed" />
    <CommandBinding Command="cs:CarSystemCommands.CopyPlateCommand" CanExecute="CopyCommand_CanExecute" Executed="CopyPlateCommand_Executed" />
</UserControl.CommandBindings>

迄今为止,我对所有这一切都有两个问题:

  1. 当我右键单击控件时,我会看到菜单,但选项是灰色的。我在 CopyCommand_CanExecute、CopyCommand_Executed 和 CopyPlateCommand_Executed 方法的开头放置了断点。到目前为止,这些断点仅在一次运行中就被击中。我不知道他们为什么在那次被击中,但之前或之后都没有。如何确保每次都调用 CanExecute 方法?

  2. 有一次断点确实被击中,参数的 Source 属性不是我认为的控件,而是 UserControl。我需要知道 UserControl 上的哪个 TextBlocks 引发了事件。我怎么做?

托尼

编辑:

UserControl 还包含一个 ComboBox 控件。我发现当我在下拉组合框后右键单击 TextBlocks 时,CanExecute 方法确实会运行。我不必在组合框中选择任何内容,只需单击它即可。

任何想法 ComboBox 可能在做什么我的代码不是?

另一件事是下拉ComboBox后,Execute事件参数的OriginalSource就是ComboBox。我想在几个 TextBlocks 上使用相同的 Copy 命令,并且我需要知道使用了哪个的上下文菜单,以便知道要复制到剪贴板的 TextBlock 的哪个文本。帮助!

4

2 回答 2

0

我找到了我的问题的部分答案。我想出了一种方法,我的代码可以确定哪个 TextBlock 的 Copy 命令是从 ContextMenu 执行的。我没有为需要此命令的三个 TextBlock 使用一个通用的 ContextMenu,而是为每个 TextBlock 创建了一个单独的 ContextMenu。然后,我在该 TextBlock 的 Copy 菜单项中添加了一个 CommandParameter,其中包含我要复制的属性的名称。然后,在 CopyCommand_Executed 事件处理程序中,我检查 e.Parameter 值的值并将相应控件的值复制到剪贴板。这很好用。

但是,直到我在 ComboBox 中选择某些内容后才会触发 CanExecute 事件的问题仍然存在。我仍然需要弄清楚这一点。

编辑:

好吧,现在一切似乎都运行良好,包括 CanExecute 事件。我正在尝试各种肯定会破坏某些东西的东西,但现在我已经让 CommandParameter 工作了,其他一切似乎都很好。我将把它标记为答案。

第二次编辑:

好吧,实际上,一切都在我发布此内容时正在处理的 UserControl 上运行。但仍然存在问题。

上面提到的UserControl其实是嵌入在另一个UserControl中的。第一个 UserControl 的内容包含在 StackPanel 中;我将 StackPanel 设置为 FocusScope,这似乎是一切开始工作的时候。

第二个控件的根有一个 StackPanel,里面有许多 Grid。第一个 Grid 包含第一个 UserControl 和其他一些东西。下面的第二个网格有两个具有 ContextMenus 的 DataGrid。它的这些 ContextMenus 现在不起作用。

我已将 StackPanel 设为 FocusScope。第一个 UserControl 上的上下文菜单不起作用,除非我将其设为 FocusScope,因此它也是一个。最后,我将包含两个 DataGrid 的 Grid 设置为 FocusScope。

我认为这个问题与 FocusScopes 有关,但我不知道它是如何关联的,而且我尝试过的任何组合都不起作用。有任何想法吗?

于 2012-01-26T22:03:03.513 回答
0

这个问题已经在我的代码中解决了。事实证明,问题在于 XAML 处理器无法确定命令的目标是什么。也就是说,它无法确定将命令发送到哪里。

我能够使用后面代码中的代码来解决这个问题。我仍然对该问题的 XAML 修复感兴趣,但我没有时间研究它。与此同时,我实施的解决方案运行良好。

对于那些感兴趣的人,这是我编写的设置命令目标的代码:

private void FixMenuItems( FrameworkElement element, Func<MenuItem, bool> condition ) {
    foreach ( MenuItem menuItem in element.ContextMenu.Items ) {
        if ( condition( menuItem ) ) {
            menuItem.CommandTarget = this;
        }
    }
}

要使用该函数,您需要将控件的引用与您尝试修复的上下文菜单一起传递给该方法,如果该属性应设置为当前对象,则将 aMenuItem作为参数的函数返回 true 。MenuItem's CommandTarget

于 2013-05-29T17:13:23.740 回答