Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTrigger to make WPF Button inactive until TextBox has value

I want the Button control's property to be IsEnabled="False" until a value is entered into a TextBox in the Window.

Code so far:

<Button
  Content="Click Me"
  Name="ClickMe"
  VerticalAlignment="Top"
  Click="ClickMe_Click">
  <Button.Style>
    <Style>
      <Style.Triggers>
        <DataTrigger
          Binding="{Binding ElementName=textBox, Path=Length}"
          <!-- or even: Binding="{Binding Path=textBox.Length}" -->
          Value="0">
          <Setter
            Property="Button.IsEnabled"
            Value="false" />
          </DataTrigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
</Button>

Also, is it possible to have this Button control's IsEnabled property be based on 3 different TextBox controls all having values?

like image 819
JohnB Avatar asked Jan 11 '11 20:01

JohnB


1 Answers

Assuming you are employing a presentation model, such as a ViewModel, you should bind directly the data instead of the UI elements.

<Style.Triggers>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding FirstName}" Value="{x:Null}" />
            <Condition Binding="{Binding MiddleName}" Value="{x:Null}" />
            <Condition Binding="{Binding LastName}" Value="{x:Null}" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Button.IsEnabled" Value="False" />
    </MultiDataTrigger>
</Style.Triggers>

That said, if you are using a presentation model, you can always add a bool "EnableSave" property and handle all the presentation logic there instead of in the view itself.

update

As can be seen by following the comments, I mistakenly set this up to enable the Button when any TextBox has a value, but the requirement is that the Button be enabled when all TextBoxes have values.

Conceptually, all you have to do is reverse the conditions -- instead of "false if all conditions false," we want "true if all conditions true."

The catch is that there is no way to say "not null" in the XAML -- no way without an IValueConverter, that is. I'd create a NullToBoolConverter that returns false for null and true for != null.

Given such a converter:

<Style.Triggers>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding FirstName,
                Converter={StaticResource NullToBoolConverter}}" Value="True" />
            <Condition Binding="{Binding MiddleName,
                Converter={StaticResource NullToBoolConverter}}" Value="True" />
            <Condition Binding="{Binding LastName,
                Converter={StaticResource NullToBoolConverter}}" Value="True" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Button.IsEnabled" Value="True" />
    </MultiDataTrigger>
</Style.Triggers>
like image 131
Jay Avatar answered Oct 26 '22 13:10

Jay