开发者

DataTrigger to make WPF Button inactive until TextBox has value

开发者 https://www.devze.com 2023-02-03 22:15 出处:网络
I want the Button control\'s property to be IsEnab开发者_运维技巧led=\"False\" until a value is entered into a TextBox in the Window.

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 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>


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>
0

精彩评论

暂无评论...
验证码 换一张
取 消