Создание WPF TabControl игнорировать Ctrl + Tab - PullRequest
2 голосов
/ 07 мая 2009

Я пишу приложение, которое использует метафору «просмотр вкладок», с TabControl в полном размере окна и другими элементами внутри вкладок. Иногда эти вкладки сами содержат другие элементы TabControl.

(Вкладки внутри вкладок могут сбивать с толку, поэтому я изменю стиль внутреннего TabControl, чтобы он не выглядел как TabControl. Вероятно, я стилизовал бы его для использования ToggleButtons вверху вместо вкладок.)

Я хочу, чтобы этот пользовательский интерфейс работал так, как вы ожидаете, что метафора просмотра с вкладками будет работать: Ctrl + Tab всегда должен переключать вкладки на внешнем TabControl (который выглядит следующим образом TabControl), даже если фокус клавиатуры находится внутри внутреннего TabControl (который не похож на TabControl, и поэтому не следует ожидать, что он будет реагировать на Ctrl + Tab ). Но, конечно, внутренний TabControl сначала получает ключевое событие и обрабатывает его сам.

Какой лучший способ не дать внутреннему TabControl реагировать на Ctrl + Tab и Ctrl + Shift + Tab ключевые события, так что эти события могут всплывать до внешнего TabControl?

Ответы [ 3 ]

3 голосов
/ 07 мая 2009

WPF TabControl, по-видимому, управляет функцией навигации по клавиатуре с помощью метода OnKeyDown. Я бы предложил создать пользовательский элемент управления, который наследуется от TabControl, и переопределить метод OnKeyDown.

1 голос
/ 18 декабря 2012

В качестве альтернативы созданию настраиваемого элемента управления, как предложено здесь , вы можете создать «прикрепленное поведение» для инкапсуляции этого:

namespace WpfApplication1
{
  using System.Windows;
  using System.Windows.Input;

  public static class IgnoreCtrlTabBehaviour
  {
    //Setter for use in XAML: this "enables" this behaviour
    public static void SetEnabled(DependencyObject depObj, bool value)
    {
      depObj.SetValue(EnabledProperty, value);
    }

    public static readonly DependencyProperty EnabledProperty =
        DependencyProperty.RegisterAttached("Enabled", typeof(bool), 
        typeof(IgnoreCtrlTabBehaviour), 
        new FrameworkPropertyMetadata(false, OnEnabledSet));

    static void OnEnabledSet(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
    {
      var uiElement = depObj as UIElement;
      uiElement.PreviewKeyDown += 
        (object _, System.Windows.Input.KeyEventArgs e) => 
        {
          if (e.Key == Key.Tab && 
              (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
          {
            e.Handled = true;
          }
        };
      }
    }
  }

Используйте в XAML следующим образом:

<Window x:Class="WpfApplication1.MainWindow"
    ...
    xmlns:local="clr-namespace:WpfApplication1"

...
<TabControl local:IgnoreCtrlTabBehaviour.Enabled="True">
  <TabItem Header="tab1">
...
1 голос
/ 07 мая 2009

Вы можете обработать событие PreviewKeyDown на своем внутреннем TabControl и установить e.Handled = true, чтобы предотвратить обработку ключевых событий. Затем вы можете найти родительский TabControl (возможно, рекурсивно через ((TabControl) отправитель) .Parent) и программно изменить его SelectedIndex.

Если поместить это в пользовательский элемент управления, он будет достаточно чистым.

...