Here is the setup (extraneous layout code removed):
Window.xaml
<Button Name="btn_Next" Command="NextPage">Next</Button>
<ContentControl Name="contentControl1" >
<Binding ElementName="MainWindow" Path="CurrentPage"/>
</ContentControl>
Window.xaml.cs Constructor
var nextCommand = new CommandBinding(NavigationCommands.NextPage);
nextCommand.CanExecute += nextCommand_CanExecute;
nextCommand.Executed += nextCommand_Executed;
CommandBindings.Add(nextCommand);
This works great in the base example, where nextCommand_CanExecute checks if the CurrentPage is the last page. However, that logic is currently just checking an array and only works for linear navigation. However, the navigation is going to be tree-like and this will not work, where the items in the contentControl1 will sometimes branch in different directions. So, I would like to have the user control that is the CurrentPage have the opportunity to override the CanExecute. My problem is that I cannot figure out how to get the UserControl to start the CanExecute. I have tried to use a number of CommandTarget settings to no avail…my child control never has it’s CanExecute method triggered. I have even tried to use the e.ContinueRouting = true in the parent window’s CanExecute. Here is the User Control code in case that helps.
User Control Constrtuctor:
var nextCommand = new CommandBinding(NavigationCommands.NextPage);
nextCommand.CanExecute += nextCommand_CanExecute;
CommandBindings.Add(nextCommand);
User Control CanExecute method:
private void nextCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
Routed command events tunnel from the root of the visual tree down to the control that initiated them, and then bubble back up. Josh Smith’s article on routed commands has a good write-up of how it works (see the “Routed” section in particular) http://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/.
The issue here is that your user control (inside of the content control), is not an “ancestor” of the button which issues the command, so the routed event never reaches it (even in passing). Given the way your visual tree is structured, I don’t think routed commands are going to be enough for you.
The first solution that comes to mind is rigging up your own mechanism for delegating CanExecute/Executed logic to your user controls. Maybe you could define a base class or interface that is implemented by all such controls which defines the various command CanExecute/Executed methods that are needed. Then you can just have a top-level implementation which casts the currently loaded control off as your interface/base class type and call the appropriate method.