DataTrigger will make the WPF button inactive until the TextBox has a value

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

The code:

 <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 for this Button control IsEnabled property to be based on 3 different TextBox controls, all of which have values?

+7
source share
3 answers

Assuming you are using a view model such as ViewModel, you should bind data directly instead of user interface 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> 

However, if you use the presentation model, you can always add the bool property "EnableSave" and handle all the presentation logic there, and not in the view itself.

Update

As you can see from the comments, I mistakenly set this to enable Button when any TextBox has a value, but the requirement is that Button be turned on when all TextBox es have values.

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

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

For 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> 
+6
source

TextBox does not have a Length property. Setting the binding path to Text.Length may work.

But a more flexible solution would be to use Converter , which can return true or false depending on the value of the string passed into it. Then you can bind the TextBox Text property like this:

At your disposal Resources:

 <localNamespace:MyEmptyStringToBooleanValueConverter x:Key="myValueConverter"/> 

Your DataTrigger definition is as follows:

 <DataTrigger Binding="{Binding ElementName=textBox, Path=Text, Converter={StaticResource myValueConverter}}" Value="False"> 

As for the second request, you can use MultiBinding . In this case, you should use a value converter to determine how to interpret the results of the binding. See the related tutorial for more details.

+3
source

Using the x: Name = "FirstName" property and similarly for others, the following code will work to enable the button when data is present in all fields.

 <Button.Style> <Style> <Style.Triggers> <DataTrigger Binding="{Binding ElementName=FirstName,Path=Text.Length, Mode=OneWay}" Value="0"> <Setter Property="Button.IsEnabled" Value="False" /> </DataTrigger> <DataTrigger Binding="{Binding ElementName=MiddleName,Path=Text.Length, Mode=OneWay}" Value="0"> <Setter Property="Button.IsEnabled" Value="False" /> </DataTrigger> <DataTrigger Binding="{Binding ElementName=LastName,Path=Text.Length, Mode=OneWay}" Value="0"> <Setter Property="Button.IsEnabled" Value="False" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style> 
0
source

All Articles