dcockerham
Topic Author
Posts: 11
Joined: 10 Apr 2021, 00:44

Directional navigation not working inside ContextMenu

11 Nov 2022, 00:45

I have a ContextMenu that doesn't seem to be receiving directional input. When one of the MenuItems has Focus, pressing up or down on a controller or keyboard does not move the Focus. As far as I can tell, the input is consumed before it reached the MenuItem. (For context, the ContextMenu is on a Border, which is inside of a ListBoxItem.)

This functionality was previously working, but seems to have stopped working when we updated from Noesis version 3.1.5-116136 to 3.1.5-11682. I can't find any local changes that would affect this, so I'm currently assuming that something changed between those versions that affected this functionality.

I noticed that there is an open bug regarding ContextMenu inputs:
https://www.noesisengine.com/bugs/view.php?id=2436
I'm not sure if that bug could be responsible for this, as it isn't a GamepadTrigger that we're using, but rather, the default navigational functionality doesn't seem to be going off. But it's similar enough that I thought I ought to note it. I am able to get a KeyTrigger with ActiveOnFocus="True" to work with these MenuItems, however, trying to handle directional input by putting up and down KeyTriggers on every MenuItem to manipulate Focus seems like a messy solution.
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

Re: Directional navigation not working inside ContextMenu

11 Nov 2022, 18:06

Hi,

We did changes to MenuItem code in relation to issues #2422 and #2431 in changeset r11642 to fix the problem you are describing now.
After that changeset I can correctly move the focus using the keyboard or a gamepad with a xaml like this:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <ListBox Width="100" Height="100">
    <ListBoxItem Content="Item 1"/>
    <ListBoxItem>
      <Border>
        <Border.ContextMenu>
          <ContextMenu>
            <MenuItem Header="View">
              <MenuItem Header="Large icons"/>
              <MenuItem Header="Small icons"/>
              <MenuItem Header="List"/>
              <MenuItem Header="Details"/>
            </MenuItem>
            <MenuItem Header="Sort by">
              <MenuItem Header="Name"/>
              <MenuItem Header="Date"/>
              <MenuItem Header="Type"/>
            </MenuItem>
            <MenuItem Header="Refresh"/>
            <Separator/>
            <MenuItem Header="Pin to TaskBar" IsCheckable="True"/>
          </ContextMenu>
        </Border.ContextMenu>
        <TextBlock Text="Item 2"/>
      </Border>
    </ListBoxItem>
    <ListBoxItem Content="Item 3"/>
  </ListBox>
</Grid>
Before that changeset using the keyboard arrows when a menu item was focused was moving the focus to the ListBox items.

Could you please confirm you see the same behavior with that xaml (before and after applying changeset 11642)?
 
dcockerham
Topic Author
Posts: 11
Joined: 10 Apr 2021, 00:44

Re: Directional navigation not working inside ContextMenu

11 Nov 2022, 22:33

Thanks, that does work, and it helped me figure out the problem! I've been adding MenuItems inside of the template, rather than inside of the ContextMenu instantiation, like so:
<ControlTemplate x:Key="ContextMenuTemplate" TargetType="ContextMenu">
    <Border>
      <StackPanel KeyboardNavigation.DirectionalNavigation="Cycle">
        <MenuItem Header="First" />
        <MenuItem Header="Second" />
        <MenuItem Header="Third" />
      </StackPanel>
    </Border>
  </ControlTemplate>
This apparently doesn't work. I had to set the StackPanel to use IsItemsHost, and then it began accepting directional input:
<ControlTemplate x:Key="ContextMenuTemplate" TargetType="ContextMenu">
    <Border>
      <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle">
    </Border>
  </ControlTemplate>
Though this means having to add the MenuItems in the instantiation instead of in the Template. Do you know if there's a way that I can separate that out, where it still works? I was trying to separate the MenuItems code to clean up some of the clutter, if that's possible. Though if it isn't possible, I can get things working with this, at least.
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

Re: Directional navigation not working inside ContextMenu

16 Nov 2022, 16:54

Hi, defining the MenuItems inside the ContextMenu template makes little sense because that will mean that all the context menus in your application using that template will have the same entries. Apart from that you are adding the MenuItems to the StackPanel in the template, they won't be added to the ContextMenu.Items collection, so the context menu doesn't know anything about them and the control logic won't work as expected.

Maybe what you are trying to do is defining the ContextMenu for a particular type of control. For example, our theme defines the following style for the TextBoxes so all instances will have the same context menu by default:
  <Style TargetType="TextBox" BasedOn="{StaticResource {x:Type Control}}">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    ...
    <Setter Property="ContextMenu">
      <Setter.Value>
        <ContextMenu>
          <MenuItem Command="ApplicationCommands.Cut"/>
          <MenuItem Command="ApplicationCommands.Copy"/>
          <MenuItem Command="ApplicationCommands.Paste"/>
        </ContextMenu>
      </Setter.Value>
    </Setter>
  </Style>
Is this what you are looking for?

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot], Semrush [Bot] and 7 guests