WPF Включить элементы управления TabItem в порядок табуляции

надеюсь, вы можете дать мне подсказку, что я делаю неправильно. Я думал, что будет довольно легко добиться того, что я пытаюсь, но я не могу решить свою проблему.

Что я хочу делать?

У меня есть форма, содержащая пару элементов управления, например. Текстовые поля слева. С правой стороны у меня есть TabControl с TabItems, и на этих элементах также есть пара, например. Текстовые поля. Первое текстовое поле слева будет иметь фокус, если я открою форму. Я ввел TabIndex таким образом, что первый TextBox на первом TabItem (который виден) должен впоследствии получить фокус. Но что бы я ни вводил, всегда все текстовые поля слева получали фокус до того, как его получил первый TabItem. Пожалуйста, найдите ниже пример кода. Что я сделал не так?

<Grid Name="grid" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="200"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <StackPanel Grid.Column="0">
        <TextBox Name="tb1" TabIndex="0" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
        <TextBox TabIndex="5" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
        <TextBox TabIndex="1" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
    </StackPanel>
    <TabControl Grid.Column="1" Height="Auto" Width="Auto" KeyboardNavigation.DirectionalNavigation="Contained">
        <TabItem Header="1">
            <StackPanel>
                <TextBox TabIndex="4" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox TabIndex="3" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox TabIndex="6" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
            <TextBox/>
            </StackPanel>
        </TabItem>
        <TabItem Header="2">
            <StackPanel>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
            </StackPanel>
        </TabItem>
    </TabControl>
</Grid>

Большое спасибо, Торстен


person TFaltinat    schedule 15.01.2014    source источник
comment
Вы решили эту проблему?   -  person Karolis Kajenas    schedule 30.03.2016


Ответы (1)


Индекс вкладки будет циклически перемещаться внутри каждого TabItem, прежде чем он попытается перейти дальше (то есть, если TabIndex определен для перехода с одной вкладки на другую, в вашем случае это не так). Так что то, что вы делаете, не сработает. Каким бы отстойным это ни было, в вашей ситуации вам придется использовать код позади, чтобы установить фокус на элемент за пределами текущего TabItem, если вы хотите прервать цикл внутренней вкладки на этом TabItem и выпрыгнуть из него в порядке, который вы описываете . Здесь я написал быстрый образец для этого:

private void TextBox_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key != Key.Tab) return;

        var textBox = (TextBox)sender;

        switch(textBox.Name)
        {
            case "tb1": 
                tab1.Focus(); 
                tb3.Focus();
                e.Handled = true;
                break;
            case "tb4": 
                tb5.Focus(); 
                e.Handled = true;
                break;
            case "tb5": 
                tab1.Focus(); 
                tb6.Focus(); 
                e.Handled = true;
                break;
        }
    }

 <Grid Name="grid" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="200"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <StackPanel Grid.Column="0">
        <TextBox Name="tb0" KeyDown="TextBox_KeyDown" TabIndex="0" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
        <TextBox Name="tb5" KeyDown="TextBox_KeyDown" TabIndex="5" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
        <TextBox Name="tb1" KeyDown="TextBox_KeyDown" TabIndex="1" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
    </StackPanel>
    <TabControl Grid.Column="1" Height="Auto" Width="Auto" KeyboardNavigation.DirectionalNavigation="Contained">
        <TabItem x:Name="tab1" Header="1" KeyboardNavigation.DirectionalNavigation="Continue">
            <StackPanel>
                <TextBox Name="tb4" KeyDown="TextBox_KeyDown" TabIndex="4" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Name="tb3" KeyDown="TextBox_KeyDown" TabIndex="3" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Name="tb6" KeyDown="TextBox_KeyDown" TabIndex="6" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox/>
            </StackPanel>
        </TabItem>
        <TabItem x:Name="tab2" Header="2">
            <StackPanel>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
                <TextBox Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=TabIndex}"/>
            </StackPanel>
        </TabItem>
    </TabControl>
</Grid>
person denis morozov    schedule 15.01.2014
comment
Неужели нет другого способа сделать это? Может через KeyboardNavigation класс? - person Karolis Kajenas; 30.03.2016