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.