0

WPF .NET 4.6

In the below code, clicking on the menu item will activate the command and correctly display:

"InkAndGesture command executed"

It is my understanding that the RoutedUICommand will travel up and down the visual tree. So how can the ProgressNoteEditor (a custom control contained within the ItemsControl) listen and act upon the custom command? (There are many instantiations of the ProgressNoteEditor) ???

Note: I need ALL instances of ProgressNoteEditor to respond, not just one, so CommandTarget is no use. Do commands only bubble up?

TIA.

I have a CustomControl (ProgressNoteEditor) which is used from the MainWindow as:

<ItemsControl x:Name="ProgressNote" Grid.Column="1" Grid.Row="1"   ItemsSource="{Binding WritingLayer.ProgressNote}" >
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <pn:ProgressNoteEditor LineCount="{Binding LineCount}" 
                                                   Background="{Binding Background}"
                                                   Vocabulary="{Binding Vocabulary}"
                                                   />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

From the Menu in the MainWindow, I have added a custom command as:

<MenuItem Header="Ink And Getsures" Command="pn:NotePadCommands.InkAndGesture"/>

The code-behind does:

private void NewProgressNoteView_Loaded(object sender, RoutedEventArgs e)
        {
            CommandBindings.Add(
                 new CommandBinding(NotePadCommands.InkAndGesture, NotePadCommands.InkAndGesture_Executed, NotePadCommands.InkAndGesture_CanExecute));
        }

For the moment, the CustomCommand is defined in its own class as:

namespace NotePad
{
    public static class NotePadCommands
    {
        // Allow InkCanvas controls to use Gestures with Ink.
        private static RoutedUICommand _InkAndGesture;

        static NotePadCommands()
        {
            _InkAndGesture = new RoutedUICommand("Allow Gestures with Ink","InkAndGesture", typeof(NotePadCommands));
        }

        // Command: InkAndGesture
        public static RoutedUICommand InkAndGesture
        {
            get { return _InkAndGesture; }
        }

        public static void InkAndGesture_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("InkAndGesture command executed");
        }
        public static void InkAndGesture_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

    }
}
Alan Wayne
  • 5,122
  • 10
  • 52
  • 95
  • 1
    If command target is not set - it starts bubbling and tunneling from element that has keyboard focus. This is probably your menu item and it cannot tunnel from it to your ProgressNoteEditors, because they are not children of menu item. But when it bubbles up - it always can reach your Window, since it's the root of visual tree. – Evk Oct 08 '17 at 19:34
  • @Evk Hmm.. So even a tunneling event would not reach the ProgressNoteEditors since they are not children of the Menu? – Alan Wayne Oct 08 '17 at 20:19
  • As far as I understand this, but it makes sense. You can try to set CommandTarget to some element from which your editors are reachable for tunneling (for example to MainWindow itself). – Evk Oct 08 '17 at 20:28

1 Answers1

1

Do commands only bubble up?

A RoutedCommand searches the visual tree from the focused element and up for an element that has a matching CommandBinding and then executes the Execute delegate for this particular CommandBinding.

So the CommandBinding of your ProgressNoteEditor element won't be found the MenuItem invokes the command, because it is not a visual ancestor of the MenuItem.

mm8
  • 163,881
  • 10
  • 57
  • 88