Фокус и TabIndex на UserControls

#wpf #user-controls #focus

#wpf #пользовательские элементы управления #фокус

Вопрос:

У меня странное поведение: у меня есть главное окно, содержащее текстовые поля и (простые) пользовательские элементы управления (текстовое поле и кнопка), но я разделил это только на текстовое поле для целей отладки.

Когда я использую текстовые поля и usercontrols БЕЗ установки свойства TabIndex, курсор перемещается по элементам управления в правильном порядке (в порядке добавления элементов управления в окно)

Когда я использую текстовые поля и usercontrols С установкой свойства TabIndex, курсор перемещается по элементам управления в недопустимом порядке (сначала все usercontrols, затем все текстовые поля), это также верно, когда для TabIndex установлено значение, соответствующее порядку, в котором был добавлен элемент управления

Вот мой usercontrol

 <UserControl x:Class="SmallControl"
             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" 
             >
        <TextBox x:Name="txTEXT" Text="{Binding Text}" />
</UserControl>
 

Следующий Mainwindow xaml приводит к порядку 000000,111111,222222,333333 , все в порядке

     <GroupBox Header="Small,Textbox,Small,TextBox without TabIndex">
        <UniformGrid Columns="4">
            <local:SmallControl Text="000000" />
            <TextBox Text="111111" />
            <local:SmallControl Text="222222" />
            <TextBox Text="333333" />
        </UniformGrid>
    </GroupBox>
 

Следующий Mainwindow xaml приводит к порядку 000000,222222,111111,333333, это НЕ нормально

     <GroupBox Header="Small,Textbox,Small,TextBox with TabIndex">
        <UniformGrid Columns="4">
            <local:SmallControl TabIndex="0" Text="000000" />
            <TextBox TabIndex="1" Text="111111" />
            <local:SmallControl TabIndex="2" Text="222222" />
            <TextBox TabIndex="3" Text="333333" />
        </UniformGrid>
    </GroupBox>
 

Есть ли способ использовать TabIndex без необходимости добавлять элементы управления в «правильном» порядке в XAML?

Ответ №1:

По умолчанию WPF считывает все элементы управления, как внутри, так и за пределами UserControls, на одном уровне табуляции (если не указано иное). Поскольку элементы управления внутри UserControl не имеют указанного TabIndex, они сохраняются с вкладками после первого цикла табуляции.

Чтобы изменить это поведение, которое я обычно устанавливаю IsTabStop="False" в своем определении UserControl, затем я привязываю внутренние элементы управления TabIndex к TabIndex UserControl

UserControl XAML

 <TextBox x:Name="txTEXT" Text="{Binding Text}" 
         TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource 
             AncestorType={x:Type local:SearchView}}}"/>
 

Использование XAML

 <GroupBox Header="Small,Textbox,Small,TextBox with TabIndex">
    <UniformGrid Columns="4">
        <local:SmallControl TabIndex="0" Text="000000" IsTabStop="False" />
        <TextBox TabIndex="1" Text="111111" />
        <local:SmallControl TabIndex="2" Text="222222" IsTabStop="False" />
        <TextBox TabIndex="3" Text="333333" />
    </UniformGrid>
</GroupBox>
 

Возможно, вы также сможете правильно настроить табуляцию, установив KeyboardNavigation .TabNavigation привязал свойство вашего UserControl к локальному. Кажется, я припоминаю, что у меня были проблемы с этим, но, честно говоря, я не могу вспомнить детали, так что это может сработать.

 <UserControl x:Class="SmallControl" ...
             KeyboardNavigation.TabNavigation="Local"  />
 

Комментарии:

1. Спасибо. Одно замечание здесь: добавление IsTabStop в usercontrol xaml для меня не сработало, оно должно быть в «usage xaml», как ответила Рейчел. ЕСЛИ у вас их много, вы можете поместить это в «parentcontrol.resources», чтобы сделать ваш xaml более читаемым.