2014-12-05 2 views
2

В WPF (MVVM, нет кода позади), скажем, у меня есть следующий код XAML:Как предотвратить закладка навигации к элементу управления, позволяя при этом курсовую навигацию к этому элементу управления

<StackPanel> 
    <Button>Normal 1</Button> 
    <Button>Special</Button> <!--This button should not tab focus, but still focus via arrow keys--> 
    <Button>Normal 2</Button> 
</StackPanel> 

По умолчанию, (1) между кнопками или (2) стрелкой вверх/вниз между кнопками. Я хочу сделать одну из кнопок - Специальная кнопка - не сфокусирована через вкладку, но все же фокусируется с помощью кнопок вверх/вниз. Я попробовал IsTabStop="False", но это также предотвращает фокусировку этой кнопки с помощью направленной навигации (стрелки вверх/вниз).

Как я могу удалить одну кнопку из вкладок навигации, в то время как продолжает позволять Направленные навигации? Вкладка и стрелка должны быть без изменений для всех остальных элементов управления.

Я пробовал комбинации IsTabStop, KeyboardNavigation.TabNavigation и KeyboardNavigation.DirectionalNavigation безрезультатно. Возможно, я не нашел правильный микс. Или, может быть, есть другой подход. Идеи?


EDIT: Хорошо, я добавляю щедрот. Чтобы быть ясным, я ищу MVVM, без кода для украшения элемента управления (например, через стиль, прикрепленное свойство, прикрепленное поведение и т. Д.), Так что он удаляется из порядка табуляции, оставаясь действительной навигационной навигацией цель. Знание жесткого кодирования элементов управления в окне (или аналогичном) неприемлемо. Это должно быть общим, многоразовым решением. Что-то вроде: <Button AllowDirectionalNavigationButPreventTabNavigation="True"/>.

+0

Это должно помочь: [WPF: Как отключить вкладки навигации без одновременного отключения клавиши со стрелкой навигации?] [1] [1]: http://stackoverflow.com/questions/4210659/wpf-how-to-disable-tab-navigation-without-also-disabling-arrow-key-navigation – Usama

+0

@Joseph Я нашел этот вопрос, но у этого человека был другой сценарий (они использовали listview), и ни один из предлагаемых решений не решает мою точную проблему. Кроме того, принятое решение использует код-позади и требует, чтобы окно узнало о поведении вкладок всех элементов управления внутри него - я хочу, чтобы элемент управления определял его собственное поведение. –

ответ

8

Как насчет этого варианта. Вы вставляете специальную кнопку в другой контейнер и кладете KeyboardNavigation.TabNavigation = «Нет» на этом контейнере. Я только что попробовал, и похоже, я могу добиться того, что вам нужно.

<StackPanel > 
    <Button>Normal 1</Button> 
    <StackPanel KeyboardNavigation.TabNavigation="None"> 
    <Button>Special</Button><!--This button should not tab focus, but still focus via arrow keys--> 
    </StackPanel> 
    <Button>Normal 2</Button> 
</StackPanel> 
+0

Это правильное решение; свойство «TabNavigation» контролирует поведение логической навигации для * дочерних элементов элемента, поэтому в случае OP «специальная» кнопка должна быть завернута в другой контейнер. –

+0

Отлично! Мой реальный сценарий был более сложным, но это была идея/информация, которую мне нужно было получить. В моем стиле пользовательского элемента управления я устанавливал «Focusable = False» и «KeyboardNavigation.TabNavigation = None». Затем, в шаблоне управления настраиваемого элемента управления, я устанавливаю 'Focusable = True', и он достигает именно того, что я хотел. –

0

здесь, как я сделал это:

<Window x:Class="MvvmLight1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:ignore="http://www.ignore.com" 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:command="http://www.galasoft.ch/mvvmlight" 
    mc:Ignorable="d ignore" 
    Height="300" 
    Width="300" 
    DataContext="{Binding Main, Source={StaticResource Locator}}"> 
<i:Interaction.Triggers> 
    <i:EventTrigger EventName="KeyDown"> 
     <command:EventToCommand Command="{Binding Mode=OneWay,Path=KeyDownCommand}" PassEventArgsToCommand="True"/> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 
<Grid x:Name="LayoutRoot"> 
    <StackPanel> 
     <Button>Normal 1</Button> 
     <Button>Special</Button> 
     <!--Should not tab focus, yet still focus via arrow keys--> 
     <Button>Normal 2</Button> 
    </StackPanel> 
</Grid> 

я использую mvvmlight и EventToCommand используется для перехвата KeyDown событие и направить его на следующую команду в ViewModel:

private RelayCommand<KeyEventArgs> _keyDownCommand; 
    public RelayCommand<KeyEventArgs> KeyDownCommand 
    { 
     get 
     { 
      return _keyDownCommand 
       ?? (_keyDownCommand = new RelayCommand<KeyEventArgs>(
       (s) => 
       { 
        if (s.Key == Key.Tab) 
        { 
         s.Handled = true; 
        } 
       })); 
     } 
    } 
+0

Спасибо, но это отключает вкладку для всего окна. Я ищу способ отключить вкладку только для одного элемента управления. –

+0

Какой контроль! вы имеете в виду StackPanel? – Usama

+0

Только одна кнопка. Специальная кнопка. Все остальные кнопки должны быть табулируемыми. Возникает вопрос: как удалить элемент управления (например,) из указателя табуляции, оставляя его как действительную направленную навигационную цель. –

Смежные вопросы