【问题标题】:WPF multibinding button.isEnabled with textboxesWPF 多绑定 button.isEnabled 与文本框
【发布时间】:2014-06-23 08:38:50
【问题描述】:

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

【问题讨论】:

  • MultiBinding 的所有参数都没有改变;它们总是相同的四个文本框。这些绑定只评估一次,因此您的 IMultiValueConverter 只会被评估一次。您可以考虑使用 BindingGroup 将所有验证规则拉入一个范围。
  • 什么意思它只在开始时起作用?当所有文本框都有效时按钮是否启用并且即使您将某个文本框更改为无效也保持为真?
  • 正如 Mike Strobel 所说,绑定在开始时只评估了一次。按钮在开始时启用,因为 Text 属性是正确的,并且当用户将文本设置为无效的内容时它不会更改。感谢您的建议,我将尝试对 BindingGroup 做一些事情

标签: c# wpf button textbox multibinding


【解决方案1】:

我不会实现 IMultiValueConverter,因为我们没有在这里转换任何东西。 BindingGroup 可以为您服务。

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

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

【讨论】:

  • 如果你能给出一个代码示例会更好。对我们来说很难理解,因为我们是 WPF 和 .NET 领域的新手。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    我所做的是使用您的 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>
    

    【讨论】:

      【解决方案4】:

      我知道这是旧的,但我有类似的需求,不想编写绑定组和验证...注意这是我的第一个 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 很好,并且在绑定时会为您抛出解析错误,但它们并没有真正为您提供一种方法来挂钩它们以更改显示给用户的消息或给您一个属性来检查是否有错误标记很烦人,但这可以让您在解析中捕获错误,而无需检查验证规则中的解析错误。我确信我的无知正在暴露,但我们都必须从某个地方开始!

      【讨论】:

        猜你喜欢
        • 2011-02-23
        • 1970-01-01
        • 2012-11-23
        • 2013-12-04
        • 2012-11-24
        • 2015-10-16
        • 2011-03-29
        • 2010-12-20
        • 2018-01-24
        相关资源
        最近更新 更多