wpftextboxeventtriggercontenttemplate

TextBox EventTrigger not setting the Property


I am trying to clear the text of a TextBox on click event of a clear button which was added to the TextBox ControlTemplate :

<Window x:Class="WpfApp1.TextBoxClearing"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"

    mc:Ignorable="d"
    Title="TextBoxClearing" Height="300" Width="300">
<Window.Resources>
    <SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFE2E3EA"/>
    <SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FFC5DAED"/>
    <SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FFB5CFE7"/>
    <Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}">
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
        <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="AllowDrop" Value="true"/>
        <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <ControlTemplate.Resources>
                        <Storyboard x:Key="OnMouseLeftButtonDown1">
                            <!-- Storyboard.TargetProperty="(TextBlock.Text)"  Storyboard.TargetName="PART_ContentHost"-->
                            <StringAnimationUsingKeyFrames Storyboard.TargetProperty="Text" 
                                                           Storyboard.Target="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TextBox}}}" >
                                <DiscreteStringKeyFrame KeyTime="0:0:0.0" Value=""/>
                            </StringAnimationUsingKeyFrames>
                        </Storyboard>
                    </ControlTemplate.Resources>
                    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <DockPanel>
                            <Button x:Name="MYPART_Clear" DockPanel.Dock="Right">X</Button>
                            <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" RenderTransformOrigin="0.5,0.5" />
                        </DockPanel>
                    </Border>
                    <ControlTemplate.Triggers>

                        <EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown" SourceName="MYPART_Clear">
                            <BeginStoryboard Storyboard="{StaticResource OnMouseLeftButtonDown1}"/>
                        </EventTrigger>
                        <Trigger Property="Text" Value="">
                            <Setter TargetName="MYPART_Clear" Property="Visibility" Value="Collapsed" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
                        </Trigger>
                        <Trigger Property="IsKeyboardFocused" Value="true">
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
                    <Condition Property="IsSelectionActive" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <TextBox VerticalAlignment="Center" HorizontalAlignment="Center" Width="150" Style="{DynamicResource TextBoxStyle1}"></TextBox>
</Grid>

Everything seems logically alright but I can't understand why it doesn't clear the text. I have tried accessing the element by its name(PART_ContentHost) or finding the parent TextBox but all of them were in vane.

Is it achievable via pure XAML? I don't like installing Blend SDK. This should be possible with this primary tools. Also custom ActionTriger which doesn't require any Nuget installation is OK.

Please pay attention that answers to similar questions require Nuget installation which is not desirable to me.


Solution

  • What I have found so on the MSDN Site

    Under the Remarks section:

    This property does not support animation.

    https://msdn.microsoft.com/en-us/library/system.windows.controls.textbox.text.aspx

    Solution (working)

    The following code is working so far. I use the Tag property for a placeholder that I want to delete the Text.

    <Window x:Class="TestBase.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestBase"
        mc:Ignorable="d"
        Title="Window2"
        SizeToContent="WidthAndHeight" d:DesignWidth="236" d:DesignHeight="187"
        MinWidth="300"
        MinHeight="300">
    <Window.Resources>
        <SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFE2E3EA"/>
        <SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FFC5DAED"/>
        <SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FFB5CFE7"/>
        <Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="AllowDrop" Value="true"/>
            <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <DockPanel>
                                <Button x:Name="MYPART_Clear" DockPanel.Dock="Right">X</Button>
                                <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" RenderTransformOrigin="0.5,0.5" />
                            </DockPanel>
                        </Border>
                        <ControlTemplate.Triggers>
                            <EventTrigger RoutedEvent="Button.Click" SourceName="MYPART_Clear">
                                <BeginStoryboard Name="FocusTrueStoryboard">
                                    <Storyboard>
                                        <StringAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(TextBlock.Tag)" 
                                            Storyboard.Target="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TextBox}}}">
                                            <DiscreteStringKeyFrame KeyTime="0:0:0" Value="delete"/>
                                            <DiscreteStringKeyFrame KeyTime="0:0:0.1" Value=""/>
                                        </StringAnimationUsingKeyFrames>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                            <Trigger Property="Tag" Value="delete">
                                <Setter Property="Text" Value=""/>
                            </Trigger>
                            <Trigger Property="Text" Value="">
                                <Setter TargetName="MYPART_Clear" Property="Visibility" Value="Collapsed" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
                            </Trigger>
                            <Trigger Property="IsKeyboardFocused" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
                        <Condition Property="IsSelectionActive" Value="false"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <TextBox x:Name="asd" VerticalAlignment="Center" HorizontalAlignment="Center" Width="150" Style="{DynamicResource TextBoxStyle1}"></TextBox>
        <TextBlock Text="{Binding ElementName=asd, Path=Tag}" VerticalAlignment="Bottom"/>
    </Grid>
    

    Preview

    preview