XAML WPF -如何设置Tab索引直接进入ContentControl内的文本框?

guz6ccqo  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(130)

我有一个自定义的TextBox模板,我已经定义了一个DataTemplate内。我使用ContentControl在视图中创建这些自定义TextBox。
TextBoxes由一个TextBox组成,它下面有空间,如果需要的话可以显示错误消息(绑定到我定义为“TextValidation”的自定义类)。
当我有一系列这样的自定义文本框时,我期望在一个文本框中按tab键,并在下一个文本框中结束。但是,每当我按Tab键时,它都会突出显示整个ContentControl。然后在第二次按下选项卡时,光标将进入文本框。
我希望能够按tab键,从一个ContentControl中的文本框直接进入下一个ContentControl中的文本框。
下面是我创建的两个文本框的视图:

<ContentControl Content="{Binding Text1}" Margin="0 0 0 10"
                ContentTemplate="{StaticResource TextBoxTemplate}"/>
<ContentControl Content="{Binding Text2}" Margin="0 0 0 10"
                ContentTemplate="{StaticResource TextBoxTemplate}"/>

Text 1和Text 2来自我定义为'TextValidation'的自定义类

public class TextValidation
    {
        public string Text;
        public bool Error;
        public string ErrorMsg;
    }

TextBoxTemplate是在ResourceDictionary中定义的(我已经删除了所有不相关的setters/styling):

<DataTemplate x:Key="TextBoxTemplate">
        <TextBox>
            <TextBox.Style>
            <Style TargetType="{x:Type TextBox}">
                <Setter Property="Text" Value="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>
                <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type TextBox}">
                                <StackPanel>
                                    <Border x:Name="border" CornerRadius="3"
                                        Background="White"
                                        BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                                        SnapsToDevicePixels="True">
                                        <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                                    </Border>
                                    <StackPanel Orientation="Horizontal" x:Name="errorMsg" Height="20">
                                        <TextBlock FontSize="12" FontStyle="Italic" Foreground="#ff3333"
                                    Text="{Binding ErrorMsg}" />
                                    </StackPanel>
                                </StackPanel>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TextBox.Style>
        </TextBox>
</DataTemplate>

有谁知道我如何修复标签索引,这样我就可以直接从一个文本框转到另一个文本框?

ffscu2ro

ffscu2ro1#

焦点转移到ContentControl。我只是简单地将“IsTabStop=“false”添加到ContentControl中,并修复了它。

ccrfmcuu

ccrfmcuu2#

我也会搜索KeyboardNavigationMode和TabNavigation,因为还有更多。
但我会从从可视化树中删除ContentControls开始,因为这是一种将DataContext设置到TextBox的繁琐方法。ContentControl的Content充当ContentTemplate中元素的DataContext。这也应该起作用:

<Grid>
    <Grid.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Text" Value="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <StackPanel>
                            <Border x:Name="border" CornerRadius="3"
                                    Background="White"
                                    BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                                    SnapsToDevicePixels="True">
                                <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                            </Border>
                            <StackPanel Orientation="Horizontal" x:Name="errorMsg" Height="20">
                                <TextBlock FontSize="12" FontStyle="Italic" Foreground="#ff3333"
                                Text="{Binding ErrorMsg}" />
                            </StackPanel>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
    <TextBox DataContext="{Binding Text1}" Margin="0 0 0 10"/>
    <TextBox DataContext="{Binding Text2}" Margin="0 0 0 10"/>
</Grid>

不要忘记在TextValidation类中实现INotifyPropertyChanged。如果因为TextBox只更新源代码,而不是相反,所以没有必要这样做,那么您可以/应该在样式设置器文本绑定中放置Mode=OneWayToSource。但至少ErrorMsg绑定需要实现INotifyPropertyChanged。

相关问题