无法在 WPF 中获取 CommandTarget

Can't get CommandTarget in WPF

说,我有以下 XAML:

<r:RibbonWindow x:Class="WPFApp.Root"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:r="urn:fluent-ribbon"
        xmlns:local="clr-namespace:WPFApp"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Title="FL Query" Height="450" Width="800">

  <Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Copy" Executed="OnCopy"/>
  </Window.CommandBindings>
  
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition/>
    </Grid.RowDefinitions>

    <r:Ribbon Grid.Row="0">

      <r:RibbonTabItem Header="Home">
        <r:RibbonGroupBox Header="ID">
          <r:TextBox x:Name="txtID" Header="ID:" Width="100"/>
          <r:Button Size="Large"
                    LargeIcon="pack://application:,,,/WPFApp;component/img/Run.png" 
                    Click="OnAction">
                    Content="Run"/>
        </r:RibbonGroupBox>
      </r:RibbonTabItem>

    </r:Ribbon>

    <Grid Grid.Row="1">
      <Label x:Name="lbl">
        <Label.ContextMenu>
          <ContextMenu>
            <MenuItem Command="ApplicationCommands.Copy"
                      CommandTarget="{Binding ElementName=lbl}"/>
          </ContextMenu>
        </Label.ContextMenu>
      </Label>
    </Grid>

  </Grid>
</r:RibbonWindow>

按下 Run 按钮后,我从数据库中检索 ID 号并将其添加到标签中。然后我尝试使用 CommandTarget 复制标签的文本(即此 ID)和标签的上下文菜单。但是,e.Source 保留对先前按下的 Run 按钮的引用:

private void OnCopy(object sender, ExecutedRoutedEventArgs e)
{
  // sender = WPFApp.Root
  // e.Source = Fluent.Ribbon
  // e.OriginalSource = class "Fluent.Button": Header = "Run", Size = Large, IsSimplified = false
    
  // label is NULL here
  var label = e.Source as Label;
  Clipboard.SetText(label.Content.ToString());
}

为什么 CommandTarget 不起作用?为什么我得到的是 Button (运行) 而不是标签?

ContextMenu 是一个弹出窗口 window,这意味着它的名称范围与其所有者不同。所以 ElementName 在这种情况下不起作用。正确的方法是使用 ContextMune.PlacementTarget 来引用所有者。

<MenuItem Command="ApplicationCommands.Copy"
          CommandTarget="{Binding PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>

关于您得到 Button 而不是 Label,我无法重现。通常,如果一个MenuItem不能解决它的CommandTarget,它应该被自动禁用。