Adding keyboard support to PopupButton

Editors for WPF Forum

Posted 3 years ago by John Lutz
Version: 16.1.0631
Avatar

I have a PopupButton that shows a treeview.   How do I programatically popup the contents?   I would like <Alt>-<Down> or F4 to open the content without using the mouse.   Similarly <Esc> should close an open PopupButton.

I have a keyboard event handler in place.  I just need to know how to programatically make the PopupButton pop.

Comments (5)

Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi John,

It looks like pressing Down will open the popup now.  And Esc should close the popup.  You can just set the IsPopupOpen property to open/close the popup in your handler.


Actipro Software Support

Posted 3 years ago by John Lutz
Avatar

IsPopupOpen works.   Next question...   Any idea how to properly get keyboard focus to go to the popup control so that I can continue navigating in the popped up control?   For example a simple list box...

Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi John,

Maybe after you set IsPopupOpen = true, you could do a Dispatcher.BeginInvoke with Loaded priority and focus your popup content?


Actipro Software Support

Posted 3 years ago by John Lutz
Avatar

I tried focusing the control and as soon as I press space bar or arrow to navigate the list box, the popup closes.   Here's the code for reference:

<UserControl x:Class="Test.Popup"
             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:ribbon="http://schemas.actiprosoftware.com/winfx/xaml/ribbon"
             mc:Ignorable="d" 
             d:DesignHeight="40" 
             d:DesignWidth="200" 
             x:Name="root">
  <Grid>
    <ribbon:PopupButton x:Name="_popupButton">
      <ribbon:PopupButton.PopupContent>
        <ListBox x:Name="_popup" FocusManager.IsFocusScope="True" SelectedIndex="{Binding Path=Type, ElementName=root, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}" BorderBrush="{x:Null}">
          <ListBox.ItemTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding Content}" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" MinHeight="22"/>
            </DataTemplate>
          </ListBox.ItemTemplate>
          <ListBoxItem Content="Choice 1"/>
          <ListBoxItem Content="Choice 2"/>
          <ListBoxItem Content="Choice 3"/>
        </ListBox>
      </ribbon:PopupButton.PopupContent>
    </ribbon:PopupButton>
  </Grid>
</UserControl>

    protected override void OnKeyDown(KeyEventArgs e)
    {
      if (e == null)
        return;

      if (e.Handled)
        return;

      Key key = e.Key;
      if (key == Key.System)
        key = e.SystemKey;

      switch (key)
      {
        case Key.Escape:
          _popupButton.IsPopupOpen = false;
          e.Handled = true;
          return;

        // Drop down
        case Key.F4:
          Popup();
          e.Handled = true;
          return;

        case Key.Up:
        case Key.Down:
          if ((e.KeyboardDevice.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
          {
            Popup();
            e.Handled = true;
          }
          return;
      }
    }

    private void Popup()
    {
      _popupButton.IsPopupOpen = true;
      _popup.Focus();
      //System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)(() =>
      //{
      //  _popup.Focus();
      //  Keyboard.Focus(_popup);
      //  //var item = _popup.SelectedItem as IInputElement;
      //  //if (item == null)
      //  //  item = _popup.Items[0] as IInputElement;
      //  //if (item != null)
      //  //{
      //  //  item.Focus();
      //  //  Keyboard.Focus(item);
      //  //}
      //}), System.Windows.Threading.DispatcherPriority.Normal);
    }
Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi John,

Sorry before I had assumed you were referring to the shared:PopupButton.  But regardless, I pasted your code above in a Window and didn't have any trouble pressing F4 to show it and use Up/Down arrow keys without it closing.  This is with th key sequence, F4, Down, Down, Up, etc.  I wouldn't recommend supporting Alt+Down as a key for navigating these since Alt modifier presses will be handled by WPF itself to close any open menus and likely popups.  You should handle regular Up/Down instead as needed while the popup is open.  But your sample seems to work fine selecting items in the list with normal Up/Down.


Actipro Software Support

The latest build of this product (v2019.1 build 0682) was released 30 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.