Mehrad
Mehrad

Reputation: 4203

DataTrigger applied to text property of a Textbox causes its binding to stop working

I have a functional binding on my TextBox which acts as a searbar. However, when I add the following trigger applied on the same binding (The first trigger), it stops the binding.

  <TextBox>
    <TextBox.Style>
      <Style TargetType="TextBox">
        <Setter Property="Text" Value="{Binding Path=SearchFilterString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        <Style.Triggers>
          <!-- 1st trigger -->
          <DataTrigger Binding="{Binding Path=SearchFilterString}" Value="">
            <Setter Property="Text" Value="Type in part name to search."/>
          </DataTrigger>
          <!-- 2nd trigger -->
          <Trigger Property="IsFocused" Value="true">
            <Setter Property="Text" Value="{x:Null}"/>
          </Trigger>
        </Style.Triggers>
      </Style>
    </TextBox.Style>
  </TextBox>

I also included the second trigger, to make sure after I fix the problem with the first one it won't create a endless loop situation. So please comment on that one as well.

The purpose of these two triggers is to show some guidline inside the TextBox to describe what is this texbox about and the guidline disapears as soon as TextBox gains focus and user attempts to type in the search keyword.Let me know if you believe there is a better approach on doing the same thing.

Upvotes: 2

Views: 1945

Answers (3)

BradleyDotNET
BradleyDotNET

Reputation: 61379

You are looking for a watermark textbox. The standard WPF TextBox does not support this behavior.

However, there are 3rd party controls available such as the one pointed out by Frank: http://wpfplayground.com/2014/06/30/watermark-behavior-for-textbox/

Ways to do your own can be found at Watermark / hint text / placeholder TextBox in WPF

Finally, you can always just overlay your own TextBox or TextBlock over the real one and hide it on focus, which will do basically the same thing.

Upvotes: 1

Mehrad
Mehrad

Reputation: 4203

This is how I achieved it using Brad's idea.

I simply put a Label with the watermark I wanted and overlapped my TextBox on top of it. All I am doing is setting the TextBox's Background property to Transparent when it's binding content is empty. When this happens you can see the label on the back.

Hence, the moment you start typing watermark disappears.

XAML

  <!-- Watermark Label -->
  <Label 
    Foreground="Gray"
    Content="Type the part name to start the search."
    />

  <!-- Search TextBox -->
  <TextBox Grid.Column="0" 
           HorizontalAlignment="Stretch" 
           >
    <TextBox.Style>
      <Style TargetType="TextBox">
        <Setter Property="Text" Value="{Binding Path=SearchFilterString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        <Style.Triggers>
          <DataTrigger Binding="{Binding Path=SearchFilterString}" Value="">
            <Setter Property="Background" Value="Transparent"/>
          </DataTrigger>
        </Style.Triggers>
      </Style>
    </TextBox.Style>
  </TextBox>

Outcome

enter image description here

Upvotes: 0

Frank
Frank

Reputation: 4481

Your binding won't work, because you are overriding it with your trigger's setter: You are setting the Text property of it to a value, while you are binding the same Text property to the view model. Both things can't work at the same time.

Essentially you're trying to create something that is called "watermark" on a textbox. I like the following the solution in particular, because it doesn't modify the TextBox itself but layers an adorner ontop of it:

Watermark Behavior for TextBox

Upvotes: 2

Related Questions