0

I have a menu in WPF that I'm trying to build dynamically using bindings and a HierarchicalDataTemplate:

        <Menu ItemsSource="{Binding MenuItems}">
            <Menu.ItemContainerStyle>
                <Style>
                    <Setter Property="cal:Message.Attach" Value="Click()" />
                </Style>
            </Menu.ItemContainerStyle>
            <Menu.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding MenuItems}">
                    <TextBlock Text="{Binding Name}" cal:Message.Attach="Click()" Background="Transparent"/>
                </HierarchicalDataTemplate>
            </Menu.ItemTemplate>
        </Menu>

An IMenuItem has a Click method, a collection of 'sub' MenuItems, and a Name displayed in the text block.

It all worked fine until I tried to get the Click to work. Since the click event is fired on the MenuItem created by the template, I don't have access to it to bind my Caliburn action with cal:Message.Attach="Click()".

I tried adding the action by using a setter in the ItemContainerStyle.

It seemed to work, however I'm getting click events firing in multiple places:

For example, if I click on "Test 2":

enter image description here

The click event on both "Test 2" model and the "Data Manager" model are fired.

Joe
  • 6,773
  • 2
  • 47
  • 81

1 Answers1

0

Mouse clicks are bubbling events. In hierarchical controls such as menus and treeviews, the child items are visual children of the parent, so a bubbling event will chase up the tree until it gets to the root item. You need to set e.Handled = true to stop it from bubbling up.

SledgeHammer
  • 7,338
  • 6
  • 41
  • 86
  • Hmm, I'm using Caliburn Actions, rather than WPF events, however they seem to do the same bubbling behaviour (but looking for same named methods in ViewModels) - problem is I can't seem to find an equivalent to `e.Handled`. I've got a work around with an event listener, but I hate having anything in my code-behind. – Joe Mar 29 '18 at 10:44
  • @Joe I don't use that MVVM framework, but it looks like they have a clean way to pass eventargs: https://caliburnmicro.com/documentation/actions in your XAML you can specify $eventargs. – SledgeHammer Mar 29 '18 at 15:59