Adding keyboard support to PopupButton

Editors for WPF Forum

Posted 4 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 4 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 4 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 4 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 4 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 4 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 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.