DataTrigger使WPF按钮无法使用,直到TextBox有值

7
我希望在窗口中的文本框输入值之前,Button控件的属性为IsEnabled="False"目前的代码:
<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>

此外,是否有可能使此 Button 控件的 IsEnabled 属性基于三个不同的 TextBox 控件都具有值?


1
哎呀,我之前已经尝试过 Binding="{Binding ViewModelDataMember}" Value="",但是 Value="{x:Null}" 才是关键。 - JohnB
3个回答

7
假设您正在使用演示模型,例如ViewModel,您应该直接绑定数据而不是UI元素。
<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>

话虽如此,如果你正在使用演示模型,你可以随时添加一个bool "EnableSave"属性,并在那里处理所有的演示逻辑,而不是在视图本身中处理。

更新

从评论中可以看出,我错误地设置了这个选项,以便在任何TextBox有值时启用Button,但要求是当所有TextBox都有值时启用Button

从概念上讲,你只需要反转条件——不是“如果所有条件都为false,则为false”,而是“如果所有条件都为true,则为true”。

问题是在XAML中没有办法说“不为空”——除非使用IValueConverter。我会创建一个NullToBoolConverter,对于null返回false,对于!= null返回true

假设有这样一个转换器:

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

然而,需要将其设置为 Property="Button.IsEnabled" - JohnB
1
@JohnB 你也可以通过声明 <Style TargetType="Button"> 来指定它是一个 Button 样式。 - Jay
1
@JohnB 尝试在绑定中添加 UpdateSourceTrigger=PropertyChangedTextBox 的默认值是 LostFocus。当您清除文本时,您可能会将值设置为空字符串而不是 null。您可以使用转换器来处理这两种情况,或者在视图模型的 setter 中添加逻辑,当 value == string.Empty 时将值设置为 null。至于数据网格和扬声器...好吧,我不知道。您可以尝试在 SuperUser.com 上提问。 - Jay
@Jay:我试过了(甚至找到了通过属性对话框来执行的方法),但现在即使第一个“TextBox”获得了值,按钮也变为活动状态。而且,我非常确定我正在使用“null”。说话者的问题可能是由于高辐射造成的!这是使用WPF的权衡。 - JohnB
1
@JohnB 抱歉,我对需求失去了追踪 - 我以为只要任何一个文本框有值就应该启用。我会更新答案以符合要求。 - Jay
显示剩余3条评论

3

TextBox没有Length属性。将绑定路径设置为Text.Length可能会起作用。

但更灵活的解决方案是使用转换器,该转换器可以根据传递给它的字符串值返回true或false。然后,您可以像这样绑定到TextBox的Text属性:

在您的控件资源中:

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

您的DataTrigger定义应该如下:

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

关于您的第二个请求,您可以使用MultiBinding来实现。在这种情况下,您必须使用一个值转换器来定义绑定结果的解释方式。请参阅链接的教程以获取详细信息。


+1,谢谢,但是<MultiDataTrigger>正是我正在寻找的。 - JohnB
1
你提到的关于Text.Length的部分对我非常有效。<CheckBox IsEnabled="{Binding ElementName=txtBox, Path=Text.Length}/> - B.K.

2

使用属性 x:Name="FirstName",以及类似的方式为其他字段,下面的代码将在所有字段中的数据存在时启用按钮。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接