I'm a bit confused about WPF commands with different target types.
So if I define a command
<Window.CommandBindings>
<CommandBinding Command="Copy"
Executed="CopyCmdExecuted"
CanExecute="CopyCmdCanExecute"/>
</Window.CommandBindings>
And now I use it in a context menu:
<ContextMenu Name="FolderContextMenu">
<MenuItem Command="Copy"/>
</ContextMenu>
And I have a method to handle the command:
private void CopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
{
}
And I use it in a plain old menu:
<Menu Name="editMenu">
<MenuItem Command="Copy"/>
</Menu>
I have no problem understanding that. But I'm a bit confused what I am supposed to do if the target objects are different types.
Lets say I have Folders and Users, both of which have a context menu with the New command (and the menu bar edit menu which also has the New command).
When New is executed, regardless of whether its a Folder or a User, CopyCmdExecuted is executed. So, am I now supposed to de-multiplex on the target? Something like
private void CopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
{
if(sender is User)
// Do copy user stuff
if(sender is Folder)
// Do copy folder stuff
}
If I end up with lots of data types I wish to copy, it seems a bit annoying. Am I not understanding something here?
(Obviously, I could just have Folder and User inherit from a Copiable base class with DoCopy but that still seems wrong.)
You can send a CommandParameter
when you invoke the Command
to indicate what you mean the command to apply to. Here's are two TextBlock
elements:
<Grid>
<StackPanel>
<TextBlock Name="textBlock1" Text="File">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem
Command="Copy"
CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
<TextBlock Name="textBlock2" Text="Folder">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem
Command="Copy"
CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</Grid>
and this code-behind:
private void CopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
{
var text = (e.Parameter as TextBlock).Text;
Debug.WriteLine("Text = " + text);
}
uses the parameter to figure out which TextBlock
the context menu applies to. You can also just use the strings "File"
and "Folder"
if that works for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With