[SOLVED] Clear TextBox's text on button click in MVVM

Issue

I’m working on a search box solution where there is no binded text as I’m using the Text property as parameter for the search command.
And that part works just fine.

Now I would like to clear the text in the TextBox using a "clear button" set at the end of the TextBox.

I tried with EventTrigger, but the StoryBoard block the Command and does not set the text to nil.

Below is my code.
Any idea?

<!--Search Box-->
<Grid Grid.Column="0">
    <TextBox x:Name="FilterText">
        <TextBox.InputBindings>
            <KeyBinding  Key="Enter" Command="{Binding FilterDataCommand}" CommandParameter="{Binding ElementName=FilterText, Path=Text}"/>
        </TextBox.InputBindings>
    </TextBox>
    <Button HorizontalAlignment="Right" Width="20" Height="20" Margin="5,0" Style="{StaticResource ButtonTransparentStyle}" Command="{Binding ClearSearchCommand}">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
                <BeginStoryboard>
                    <Storyboard>
                        <StringAnimationUsingKeyFrames Storyboard.TargetName="FilterText" Storyboard.TargetProperty="Text">
                            <DiscreteStringKeyFrame KeyTime="0:0:1" Value=""/>
                        </StringAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
        <Image Source="/VisionRanger;component/Images/Icons/icon.clear.dark.png" Stretch="UniformToFill" Margin="4,3,2,4" Opacity="0.5"/>
    </Button>
</Grid>
<!--Search Button-->
<Button Grid.Column="1"  Style="{StaticResource ButtonTransparentStyle}" Margin="5,0,0,0" Width="25" HorizontalAlignment="Left"
    Command="{Binding FilterDataCommand}" CommandParameter="{Binding ElementName=FilterText, Path=Text}">
    <Image Source="/VisionRanger;component/Images/Icons/icon.search.dark.png" Stretch="UniformToFill"/>
</Button>

Solution

The obvious way for me is to create a custom control. But I needed something that I could use quickly for a client’s project so I created a style that leveraged the properties of a button to create a search "button" (Of course there were other styles involved) but they don’t change the underlying principle used.

Without Text

And when there is text, clicking the close button will clear it.

With Text

<!--#region Search Button-->
<Style
    x:Key="SearchButton"
    BasedOn="{StaticResource BaseStyle}"
    TargetType="{x:Type Button}">
    <Setter Property="Tag" Value="{StaticResource SearchIcon}" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ButtonBase}">
                <Border
                    x:Name="border"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    CornerRadius="5"
                    SnapsToDevicePixels="True">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>

                        <!--#region Search Icon-->
                        <Border
                            Grid.Column="0"
                            Margin="{TemplateBinding Padding}"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center">
                            <Button
                                Name="icon"
                                Background="{TemplateBinding Background}"
                                Command="{TemplateBinding Command}"
                                CommandParameter="{Binding Text, ElementName=text}"
                                Content="{TemplateBinding Tag}"
                                FontSize="{TemplateBinding FontSize}"
                                Foreground="{TemplateBinding Foreground}"
                                IsDefault="True"
                                Style="{StaticResource IconButton}" />
                        </Border>
                        <!--#endregion-->

                        <!--#region Text Box-->
                        <Border Grid.Column="1" Margin="5">
                            <TextBox
                                Name="text"
                                VerticalAlignment="Center"
                                HorizontalContentAlignment="Left"
                                VerticalContentAlignment="Center"                                  
                                ClipToBounds="True"
                                FontSize="{TemplateBinding FontSize}"
                                Foreground="{TemplateBinding Foreground}"
                                Style="{StaticResource TextBoxWithPlaceHolder}"
                                Tag="{TemplateBinding Content}"
                                TextWrapping="NoWrap">
                                <TextBox.InputBindings>
                                    <KeyBinding
                                        Key="Enter"
                                        Command="{TemplateBinding Command}"
                                        CommandParameter="{Binding Text, ElementName=text}" />
                                </TextBox.InputBindings>
                            </TextBox>
                        </Border>
                        <!--#endregion-->

                        <!--#region Close Icon-->
                        <Button
                            Name="close"
                            Grid.Column="2"
                            Margin="5"
                            FontSize="{TemplateBinding FontSize}"
                            Foreground="{TemplateBinding Foreground}"
                            IsCancel="True"
                            Style="{StaticResource CloseButtonStyle}">
                            <TextBlock FontFamily="{StaticResource IconSolid}" Text="{StaticResource CloseIcon}" />
                        </Button>
                        <!--#endregion-->

                    </Grid>
                </Border>

                <!--#region Triggers-->
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding Text, ElementName=text}" Value="">
                        <Setter TargetName="icon" Property="IsEnabled" Value="False" />
                        <Setter TargetName="close" Property="Visibility" Value="Collapsed" />
                    </DataTrigger>
                    <Trigger SourceName="close" Property="IsPressed" Value="True">
                        <Setter TargetName="text" Property="Text" Value="" />                           
                    </Trigger>
                </ControlTemplate.Triggers>
                <!--#endregion-->

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<!--#endregion-->

At any point in code, I define a button and call this style on it, and bind its command.

<Button
       Width="400"
       Height="50"
       Margin="10"
       HorizontalAlignment="Left"
       Background="Transparent"
       Command="{Binding SearchCommand}"
       Style="{StaticResource SearchButton}" />

I believe there are better ways to do this but this has worked for me by far.

Answered By – Jeffery

Answer Checked By – Jay B. (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *