I want the Button
control's property to be IsEnab开发者_运维技巧led="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?
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 TextBox
es 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>
TextBox
doesn't have a Length
property. Setting your binding Path to Text.Length
might work.
But a more-flexible solution would be to use a Converter, which can return true or false based on the value of the string passed into it. You can then bind to the TextBox's Text property, like so:
In your control's Resources:
<localNamespace:MyEmptyStringToBooleanValueConverter x:Key="myValueConverter"/>
Your DataTrigger definition then looks like this:
<DataTrigger Binding="{Binding ElementName=textBox, Path=Text,
Converter={StaticResource myValueConverter}}"
Value="False">
As for your second request, you can use a MultiBinding. In this case, you must use a value converter to define how the results of the binding should be interpreted. See the linked tutorial for details.
Using property x:Name="FirstName" and similarly for others following code will work to enable the button when the data is present in all the 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>
精彩评论