Home > Enterprise >  Can't get CommandTarget in WPF
Can't get CommandTarget in WPF

Time:02-26

Say, I have the following 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>

Upon pressing Run button I retrieve ID number from database and put it to label. Then I'm trying to copy label's text (i.e. this ID) with label's context menu by using CommandTarget. However, e.Source holds reference to previously pressed Run button:

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());
}

Why CommandTarget doesn't work? Why do I get Button (Run) instead of a label?

CodePudding user response:

ContextMenu is a popup window, that means that it has different name scope then its owner. So ElementName will not work in this situation. The right way is use ContextMune.PlacementTarget to reference to the owner.

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

And about you getting Button instead of Label, I just can't reproduce that. Normally, if a MenuItem can't solve its CommandTarget, it should be disabled automatically.

  • Related