Reputation: 5444
I am trying to use RoutedCommands in my UserControls, following the example in this article:
https://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/
I defined the RoutedCommand and CommandBindings in the UserControl instead of in the article's example. I am trying to use it in my MainWindow, so that when the Button is clicked, the Command in the UserControl is executed. However, the Button is disabled and the Foo_CanExecute()
method is never executed.
<UserControl x:Class="RoutedCommandTest.ViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:RoutedCommandTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.CommandBindings>
<CommandBinding
Command="{x:Static local:ViewControl.Foo}"
PreviewCanExecute="Foo_CanExecute"
PreviewExecuted="Foo_Executed"
/>
</UserControl.CommandBindings>
<Grid>
</Grid>
</UserControl>
Here is the code for ViewControl.xaml.cs
:
public static readonly RoutedCommand Foo = new RoutedCommand();
void Foo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void Foo_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("The Window is Fooing...");
}
public ViewControl()
{
InitializeComponent();
}
And here is the code for MainWindow.xaml
:
<Window x:Class="RoutedCommandTest.MainWindow"
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:local="clr-namespace:RoutedCommandTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:ViewControl/>
<Button Content="Foo" Margin="0 5" Command="{x:Static local:ViewControl.Foo}"/>
</Grid>
</Window>
I would like to know how to fix the issue so that the Button is enabled and the Foo_CanExecute()
method is executed when the Button is clicked.
Upvotes: 1
Views: 768
Reputation: 12276
Your command is in a usercontrol, whilst the button is in mainwindow.
Which presumably contains your usercontrol.
Like bubbling and routing events ( which are used to drive them ).
Executed looks for the command bubbling UP the visual tree to the binding.
PreviewExecuted looks for the command tunnelling DOWN the visual tree to the binding.
Since your button is in the parent of the usercontrol I'm not sure whether either bubbling or tunnelling will work.
But tunnelling would be PreviewExecuted And PreviewCanExecute.
Routedcommands can be pretty tricky to get right.
One thing you sometimes have to do is to bind commandtarget to tell it where to go look.
eg:
<Grid>
<local:UserControl1 x:Name="UC1" Height="60" Width="100"/>
<Button Content="Foo" TextElement.FontSize="30" Command="{x:Static local:UserControl1.Foo}"
CommandTarget="{Binding ElementName=UC1}"
/>
</Grid>
Works for me.
I have rarely found them useful - this is one of the aspects makes them way less useful than you might at first imagine.
EDIT:
It's perhaps worth mentioning the other thing makes these unattractive compared to a regular icommand. You need to either use a static which means it's only suitable for very generic commands OR you need event handlers which will be in code behind.
On the other hand.
If you're writing something has to work generically with whatever has focus. Like say a text editor with multiple textboxes and you're doing text manipulation. A routed command might be suitable. I have never encountered such a requirement in apps I've worked on though.
Upvotes: 4