user924270
user924270

Reputation:

Textbox visiblity not changing in WPF TabItem Header

I have created a style for TabItem. When tabItem header is double-clicked then a textbox shows up so that the header text can be edited.

I want to hide that textbox when a tab selection is changed or tab loses focus so I am setting visibility to false when IsSelected is false or when SelectionChanged event is fired but its NOT working.

<Trigger Property="IsSelected" Value="false">
    <Setter Property="Visibility" Value="{x:Static Visibility.Collapsed}" TargetName="tabHeaderEdit" />
    <Setter Property="Visibility" Value="{x:Static Visibility.Visible}" TargetName="tabHeaderPresenter" />
    <Setter TargetName="tabDockPanel" Property="Background" Value="#FFC9C7BA" />
</Trigger>

<EventTrigger RoutedEvent="Selector.SelectionChanged">
    <BeginStoryboard Storyboard="{StaticResource endHeaderEdit}"/>
</EventTrigger>

Here is the full XAML. Can some one please tell me what wrong with this xaml?

<Window x:Class="WpfApplication1.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic" 
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="Window1" Height="300" Width="300">
<Window.Resources>
    <Storyboard x:Key="startHeaderEdit">
        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="tabHeaderEdit" Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="tabHeaderPresenter" Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="endHeaderEdit">
        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="tabHeaderEdit" Storyboard.TargetProperty="(UIElement.Visibility)" >
            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="tabHeaderPresenter" Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    <LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientBrush.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="#FFF" Offset="0.0"/>
                <GradientStop Color="#EEE" Offset="1.0"/>
            </GradientStopCollection>
        </GradientBrush.GradientStops>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
    <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
    <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
    <SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" />
    <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
    <Style x:Key="{x:Type TabItem}" TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">           
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">                        
                    <theme:ClassicBorderDecorator Name="ClassicBorder" SnapsToDevicePixels="true" BorderStyle="TabTop" Background="{TemplateBinding Background}" BorderBrush="{x:Static theme:ClassicBorderDecorator.ClassicBorderBrush}" BorderThickness="2">
                        <DockPanel x:Name="tabDockPanel">
                            <Button x:Name="tabCloseButton" Content="X" Cursor="Hand" DockPanel.Dock="Right" Focusable="False" FontFamily="Courier" FontSize="9" FontWeight="Bold" Margin="5,2,3,2" Padding="0" VerticalContentAlignment="Bottom" Width="16" Height="16"/>
                            <TextBox x:Name="tabHeaderEdit" DockPanel.Dock="Left" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" Visibility="Collapsed">                                    
                            </TextBox>
                            <ContentPresenter x:Name="tabHeaderPresenter" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="true" HorizontalAlignment="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" VerticalAlignment="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                        </DockPanel>
                    </theme:ClassicBorderDecorator>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="Panel.ZIndex" Value="1" />
                        </Trigger>
                        <Trigger Property="IsSelected" Value="false">
                            <Setter Property="Visibility" Value="{x:Static Visibility.Collapsed}" TargetName="tabHeaderEdit" />
                            <Setter Property="Visibility" Value="{x:Static Visibility.Visible}" TargetName="tabHeaderPresenter" />
                            <Setter TargetName="tabDockPanel" Property="Background" Value="#FFC9C7BA" />
                        </Trigger>
                        <EventTrigger RoutedEvent="Control.MouseDoubleClick">
                            <BeginStoryboard Storyboard="{StaticResource startHeaderEdit}"/>
                        </EventTrigger>
                        <EventTrigger RoutedEvent="Selector.SelectionChanged">
                            <BeginStoryboard Storyboard="{StaticResource endHeaderEdit}"/>
                        </EventTrigger>
                        <!--<EventTrigger RoutedEvent="Mouse.MouseLeave">
                            <BeginStoryboard Storyboard="{StaticResource endHeaderEdit}"/>
                        </EventTrigger>-->
                        <Trigger Property="TabStripPlacement" Value="Bottom">
                            <Setter TargetName="ClassicBorder" Property="BorderStyle" Value="TabBottom" />
                        </Trigger>
                        <Trigger Property="TabStripPlacement" Value="Left">
                            <Setter TargetName="ClassicBorder" Property="BorderStyle" Value="TabLeft" />
                        </Trigger>
                        <Trigger Property="TabStripPlacement" Value="Right">
                            <Setter TargetName="ClassicBorder" Property="BorderStyle" Value="TabRight" />
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true" />
                                <Condition Property="TabStripPlacement" Value="Top"  />
                            </MultiTrigger.Conditions>
                            <Setter Property="Margin" Value="-2" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true" />
                                <Condition Property="TabStripPlacement" Value="Bottom" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Margin" Value="-2" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true" />
                                <Condition Property="TabStripPlacement" Value="Left" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Padding" Value="11,2,14,2" />
                            <Setter Property="Margin" Value="-2" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true" />
                                <Condition Property="TabStripPlacement" Value="Right" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Padding" Value="14,2,11,2" />
                            <Setter Property="Margin" Value="-2" />
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Value="{DynamicResource {x:Static SystemColors.GrayTextBrush}}" Property="Foreground" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>        
</Window.Resources>
<TabControl Name="tabControlView" Margin="4" BorderThickness="1" BorderBrush="Black">
    <TabControl.Items>
        <TabItem Header="Header 1" Content="Content 1" HorizontalAlignment="Left" VerticalAlignment="Top"></TabItem>
        <TabItem Header="Header 2" Content="Content 2"  HorizontalAlignment="Left" VerticalAlignment="Top"></TabItem>
        <TabItem Header="Header 3" Content="Content 3"  HorizontalAlignment="Left" VerticalAlignment="Top"></TabItem>
    </TabControl.Items>
</TabControl>

Upvotes: 1

Views: 658

Answers (1)

brunnerh
brunnerh

Reputation: 184376

How about stop editing on LostFocus:

<EventTrigger SourceName="tabHeaderEdit" RoutedEvent="UIElement.LostFocus">
    <BeginStoryboard Storyboard="{StaticResource endHeaderEdit}"/>
</EventTrigger>

(At least that works, and it probably is more in line with how it is usually done)

Edit: The SelectionChanged trigger never fires as the event belongs to the TabControl and not the TabItem which is being templated, further the Setters cannot change the values as they have been animated by the storyboard. this would work:

<Trigger Property="IsSelected" Value="false">
    <Trigger.EnterActions>
        <StopStoryboard BeginStoryboardName="start"/>
        <BeginStoryboard Name="end" Storyboard="{StaticResource endHeaderEdit}"/>
    </Trigger.EnterActions>
    <Setter TargetName="tabDockPanel" Property="Background" Value="#FFC9C7BA" />
</Trigger>
<EventTrigger RoutedEvent="Control.MouseDoubleClick">
    <BeginStoryboard Name="start" Storyboard="{StaticResource startHeaderEdit}"/>
</EventTrigger>

I would still recommend to use the first method though, it is a bit irritating if the TextBox stays even after clicking away while staying on the same tab.

Upvotes: 0

Related Questions