Search code examples
silverlight-4.0c#-4.0tabbing

Tabbing in a TreeView Silverlight 4.0


I have a tree view. I am creating the tree view items dynamically. Each tree view item has a stack panel for a header. The stack panel contains a label, four text boxes, and two buttons. I have a class-level tab index counter. On text box creation, I set the tab index equal to the tab index counter, and increment. The fourth text box and two buttons do not get assigned a tab index, and IsTabStop is set to false. Not setting tab indexes on the text boxes has the same outcome.

With the setup of my situation complete, when I tab inside any of the text boxes, it gives focus to the first text box in the next tree view item instead of the next text box in the header of the current tree view item.

What's up with that?

I've been doing research and I found this: http://social.msdn.microsoft.com/Forums/en/wpf/thread/98423dda-23c5-4480-b588-50ea9d313b64

Only problem is that TabNavigation.Continue doesn't exist in SL4.


Solution

  • I think what you might need to do is to first create an ItemContainerStyle for a TreeViewItem, then in the style, replace the ContentPresenter inside the Header button with a ContentControl (inherits from Control which allows IsTabStop). Then you should be able to tab thru controls in your StackPanel without setting any tab index.

    Please give it a try and let me know if it helps. :)

    ItemContainerStyle:

        <Style TargetType="sdk:TreeViewItem">
            <Setter Property="Padding" Value="3"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Cursor" Value="Arrow"/>
            <Setter Property="IsTabStop" Value="False"/>
            <Setter Property="TabNavigation" Value="Once"/>
            <Setter Property="Margin" Value="0 1 0 0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="sdk:TreeViewItem">
                        <Grid Background="{x:Null}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="15"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver"/>
                                    <VisualState x:Name="Pressed"/>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Header">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <SolidColorBrush Color="#FF999999"/>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected"/>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To=".75" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Selection"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedInactive">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To=".2" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Selection"/>
                                            <ColorAnimation Duration="0" To="#FF999999" Storyboard.TargetProperty="Color" Storyboard.TargetName="SelectionFill"/>
                                            <ColorAnimation Duration="0" To="#FF333333" Storyboard.TargetProperty="Color" Storyboard.TargetName="SelectionStroke"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="HasItemsStates">
                                    <VisualState x:Name="HasItems"/>
                                    <VisualState x:Name="NoItems">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ExpanderButton">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ExpansionStates">
                                    <VisualState x:Name="Collapsed"/>
                                    <VisualState x:Name="Expanded">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ItemsHost">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ValidationStates">
                                    <VisualState x:Name="Valid"/>
                                    <VisualState x:Name="InvalidUnfocused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="Validation">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="InvalidFocused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="Validation">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="ValidationToolTip">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <System:Boolean>True</System:Boolean>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ToggleButton x:Name="ExpanderButton" HorizontalAlignment="Stretch" IsTabStop="False" TabNavigation="Once" VerticalAlignment="Stretch">
                                <ToggleButton.Template>
                                    <ControlTemplate TargetType="ToggleButton">
                                        <Grid x:Name="Root" Background="Transparent">
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroup x:Name="CommonStates">
                                                    <VisualState x:Name="Normal"/>
                                                    <VisualState x:Name="MouseOver">
                                                        <Storyboard>
                                                            <ColorAnimation Duration="0" To="#FF1BBBFA" Storyboard.TargetProperty="(Path.Stroke).Color" Storyboard.TargetName="UncheckedVisual"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Disabled">
                                                        <Storyboard>
                                                            <DoubleAnimation Duration="0" To=".7" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                                <VisualStateGroup x:Name="CheckStates">
                                                    <VisualState x:Name="Unchecked"/>
                                                    <VisualState x:Name="Checked">
                                                        <Storyboard>
                                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="UncheckedVisual"/>
                                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckedVisual"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                            </VisualStateManager.VisualStateGroups>
                                            <Grid HorizontalAlignment="Right" Margin="2 2 5 2">
                                                <Path x:Name="UncheckedVisual" Data="M 0,0 L 0,9 L 5,4.5 Z" Fill="#FFFFFFFF" HorizontalAlignment="Right" Height="9" Stroke="#FF989898" StrokeThickness="1" StrokeLineJoin="Miter" VerticalAlignment="Center" Width="6"/>
                                                <Path x:Name="CheckedVisual" Data="M 6,0 L 6,6 L 0,6 Z" Fill="#FF262626" HorizontalAlignment="Center" Height="6" Opacity="0" StrokeLineJoin="Miter" VerticalAlignment="Center" Width="6"/>
                                            </Grid>
                                        </Grid>
                                    </ControlTemplate>
                                </ToggleButton.Template>
                            </ToggleButton>
                            <Rectangle x:Name="Selection" Grid.Column="1" IsHitTestVisible="False" Opacity="0" RadiusY="2" RadiusX="2" StrokeThickness="1">
                                <Rectangle.Fill>
                                    <SolidColorBrush x:Name="SelectionFill" Color="#FFBADDE9"/>
                                </Rectangle.Fill>
                                <Rectangle.Stroke>
                                    <SolidColorBrush x:Name="SelectionStroke" Color="#FF6DBDD1"/>
                                </Rectangle.Stroke>
                            </Rectangle>
                            <Button x:Name="Header" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Cursor="{TemplateBinding Cursor}" ClickMode="Hover" Grid.Column="1" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsTabStop="False" TabNavigation="Once" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Grid Background="{TemplateBinding Background}">
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroup x:Name="CommonStates">
                                                    <VisualState x:Name="Normal"/>
                                                    <VisualState x:Name="Pressed">
                                                        <Storyboard>
                                                            <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Hover"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Disabled">
                                                        <Storyboard>
                                                            <DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Content"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                            </VisualStateManager.VisualStateGroups>
                                            <Rectangle x:Name="Hover" Fill="#FFBADDE9" IsHitTestVisible="False" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#FF6DBDD1" StrokeThickness="1"/>
                                            <ContentControl x:Name="Content" Cursor="{TemplateBinding Cursor}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" IsTabStop="False"/>
                                        </Grid>
                                    </ControlTemplate>
                                </Button.Template>
                                <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}"/>
                            </Button>
                            <Border x:Name="Validation" BorderBrush="#FFDB000C" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" CornerRadius="2" Visibility="Collapsed">
                                <ToolTipService.ToolTip>
                                    <ToolTip x:Name="ValidationToolTip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" IsHitTestVisible="True" Placement="Right" PlacementTarget="{Binding ElementName=Header}" Template="{StaticResource CommonValidationToolTipTemplate}"/>
                                </ToolTipService.ToolTip>
                                <Grid Background="Transparent" HorizontalAlignment="Right" Height="10" Margin="0,-4,-4,0" VerticalAlignment="Top" Width="10">
                                    <Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 Z" Fill="#FFDC000C" Margin="-1,3,0,0"/>
                                    <Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#FFFFFFFF" Margin="-1,3,0,0"/>
                                </Grid>
                            </Border>
                            <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1" Visibility="Collapsed"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>