WPF multibinding button.isEnabled with textboxes

时间:2014-05-06 16:07:03

标签: c# wpf button textbox multibinding

我是WPF的新手,我无法在网上找到解决方案。我的问题是,我希望只有当四个文本框没有有效性错误时才启用我的按钮。 我的代码是:

<Button Content="Action" Click="Action_Click" >
      <Button.IsEnabled>
          <MultiBinding Converter="{StaticResource ValCon}">
               <Binding ElementName="textBox1" />
               <Binding ElementName="textBox2"/>
               <Binding ElementName="textBox3"/>
               <Binding ElementName="textBox4"/>
          </MultiBinding>
       </Button.IsEnabled>
</Button>

我的多值转换器就像:

class ValidityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool b = true;
        foreach (var x in values)
        {
            TextBox y = x as TextBox;
            if (Validation.GetHasError(y))
            {
                b = false;
                break;
            }
        }
        return b;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我注意到这只是在开始时才有效。当用户修改其中一个文本框时,它不会。我的值转换器是否需要实现INotifyPropertyChange?在WPF中做这样的事情的正确解决方案是什么?谢谢你的帮助。

修改

我已经做过类似的事情并且正在工作:

                       <Button Click="Button_Click"  >
                            <Button.Style>
                                <Style TargetType="Button">
                                    <Setter Property="IsEnabled" Value="False"/>
                                    <Style.Triggers>
                                        <MultiDataTrigger>
                                            <MultiDataTrigger.Conditions>
                                                <Condition Binding="{Binding Path=(Validation.HasError), ElementName=textBox}" Value="False"/>
                                                <Condition Binding="{Binding Path=(Validation.HasError), ElementName=textBox1}" Value="False"/>
                                                <Condition Binding="{Binding Path=(Validation.HasError), ElementName=textBox2}" Value="False"/>
                                                <Condition Binding="{Binding Path=(Validation.HasError), ElementName=textBox3}" Value="False"/>
                                            </MultiDataTrigger.Conditions>
                                            <Setter Property="IsEnabled" Value="True"/>
                                        </MultiDataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Button.Style>
                        </Button>

4 个答案:

答案 0 :(得分:2)

我不会实现IMultiValueConverter,因为我们在这里没有转换任何东西。 BindingGroup可以满足您的需求。

使用MVVM / INotifyPropertyChanged的同样有效的方法可以如下: -

  1. 将按钮的IsEnabled属性绑定到布尔属性(比如说IsValid)。
  2. 将所有文本框绑定到不同的属性。
  3. 任何这些文本框的OnPropertyChange,调用一个公共函数(比如Validate())
  4. 可以根据Validate()将IsValid设置为true或false,然后依次切换(启用/禁用)按钮的状态。

答案 1 :(得分:2)

我所做的就是使用你的MultiTrigger解决方案,但在我的情况下我想要一个按钮只有当3个文本框的长度为零时才会激活,所以我的解决方案可以使用下面的代码。

<Button.Style>
   <Style TargetType="Button">
       <Setter Property="IsEnabled" Value="True"/>
           <Style.Triggers>
                 <MultiDataTrigger>
                     <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=Text.Length, ElementName=activationKeyTextbox}" Value="0"/>
                     </MultiDataTrigger.Conditions>
                     <Setter Property="IsEnabled" Value="False"/>
                     </MultiDataTrigger>
                     <MultiDataTrigger>
                     <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=Text.Length, ElementName=serialDayStartbox}" Value="0"/>
                     </MultiDataTrigger.Conditions>
                     <Setter Property="IsEnabled" Value="False"/>
                     </MultiDataTrigger>
                     <MultiDataTrigger>
                     <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Text.Length, ElementName=serialNumdaysbox}" Value="0"/>
                 </MultiDataTrigger.Conditions>
                 <Setter Property="IsEnabled" Value="False"/>
             </MultiDataTrigger>
        </Style.Triggers>
    </Style>
 </Button.Style>

答案 2 :(得分:1)

我知道这是旧的,但我有类似的需求,并且不想写一个绑定组和验证...注意这是我的第一个wpf应用程序,第一次使用mvvm!

<Button Name="AddBtn" Content="Add" Grid.Row="2" Grid.Column="2" Height="30" Width="100" Command="{Binding AddCmd}" CommandParameter="{Binding Pending}" >
  <Button.IsEnabled>
     <MultiBinding Converter="{StaticResource multiButtonEnabled}" >
          <Binding ElementName="tb1" Path="(Validation.Errors)[0]" />
          <Binding ElementName="tb2" Path="(Validation.Errors)[0]"  />
          <Binding ElementName="tb3" Path="(Validation.Errors)[0]" />
     </MultiBinding>
  </Button.IsEnabled>
</Button>

转换器看起来像这样

[ValueConversion(typeof(ValidationError), typeof(bool))]
class TxtBoxMultiEnableConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        int i=0;
        foreach (var item in values)
        {
            if (item as ValidationError != null)
            {
                i++;
            }
        }
        if (i!=0)
        {
            return false;
        }
        return true;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

我使用IDataErrorInfo来捕获模型中的错误,并绑定到double。 WPF很好,并在绑定时为您抛出解析错误,但它们并没有真正为您提供一种方法来挂钩它们来更改显示给用户的消息,或者为您提供一个属性来检查是否有标记的错误很烦人,但是这可以让你在解析时捕获错误,而不必检查验证规则中的解析错误。我确信我的无知正在显现,但我们都必须从某个地方开始!

答案 3 :(得分:0)

正如Mike所说,文本框没有改变。

你应该绑定textbox.Text属性。

在你的例子中:

<Button Content="Action" Click="Action_Click" >
      <Button.IsEnabled>
          <MultiBinding Converter="{StaticResource ValCon}">
               <Binding ElementName="textBox1" Path="Text"/>
               <Binding ElementName="textBox2" Path="Text" />
               <Binding ElementName="textBox3" Path="Text"/>
               <Binding ElementName="textBox4" Path="Text"/>
          </MultiBinding>
       </Button.IsEnabled>
</Button>
相关问题