◇Pile Up◇ --Keenag Blog--

プログラミング備忘録ブログです。C#、WPFの記事が中心となります。

【WPF】タブ順指定ではまりかけた話

XAMLではTabIndexを指定することで、ユーザのタブ操作によるフォーカスの順番を設定することができますが、 Windowの中にUserControlを表示するような画面の場合、少しはまりかけたので、備忘録として残します。 以下サンプルコードで説明していきます。
なお、今回も一部のソースコードの説明は割愛しています。詳細はサンプルコードを参考にしてください。

MainWindow.xaml

MainWindow.xamlクラスは、WindowのLoadedイベントで、MainwindowViewModel.csのNavigateCommandが呼ばれ、ContentControl部分にMainWindowViewModel.csで指定したUserControlが組み込まれるという作りになっています。

<Window x:Class="TabIndexSample.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="TabIndexSample" Height="350" Width="525">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding NavigateCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid>
        <ContentControl prism:RegionManager.RegionName="ContentRegion"
                        FocusVisualStyle="{StaticResource FocusVisualStyleKey}"/>
    </Grid>
</Window>

HogeUserControl.xaml

HogeUserControl.xamlは、MainWindow.xamlのContentControlに表示されるUserControlで、 TabIndexでユーザのタブ操作を制御しています。

<UserControl x:Class="TabIndexSample.Views.HogeUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True"
             Height="350"
             Width="525"
             Background="LightSlateGray">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="100"/>
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>
        <Label Grid.Row="0"
               Content="TabIndex1"
               HorizontalAlignment="Left"
               VerticalAlignment="Center"
               Margin="90,0,0,0"/>
        <TextBox Grid.Row="0"
                 Width="200"
                 Height="30"
                 TabIndex="1"
                 FocusVisualStyle="{StaticResource FocusVisualStyleKey}"/>
        <Label Grid.Row="1"
               Content="TabIndex2"
               HorizontalAlignment="Left"
               VerticalAlignment="Center"
               Margin="90,0,0,0"/>
        <TextBox Grid.Row="1"
                 Width="200"
                 Height="30"
                 TabIndex="2"
                 FocusVisualStyle="{StaticResource FocusVisualStyleKey}"/>
        <Label Grid.Row="2"
               Content="TabIndex0"
               HorizontalAlignment="Left"
               VerticalAlignment="Center"
               Margin="90,0,0,0"/>
        <TextBox Grid.Row="2"
                 Width="200"
                 Height="30"
                 TabIndex="0"
                 FocusVisualStyle="{StaticResource FocusVisualStyleKey}"/>
    </Grid>
</UserControl>

実行結果(修正前)

このソースコードで実行すると、実行結果はこのようになります。

HogeUserControl.xaml内のTab操作を終えると、タブのフォーカスが画面全体にあたってしまいます。
これでは、意図していたタブ操作ではありません。 そこで、HogeUserControlのUserControlタグに

IsTabStop="False"

を追加してみたのですが、結果は変わりません。
UserContorolの表示元であるMainWindow.xamlのContentControlにIsTabStop="False"を追加することで解決することができました。

        <ContentControl prism:RegionManager.RegionName="ContentRegion"
                        FocusVisualStyle="{StaticResource FocusVisualStyleKey}"
                        IsTabStop="False"/>

実行結果(修正後)

修正後の実行結果はこのようになります。
無事、画面全体へのフォーカスが外れました。

サンプルコード

以下に公開しています。
https://github.com/Keenag/SampleCode/tree/master/TabIndexSample