【问题标题】:Make checkbox bound to nullable bool transition from null to true使复选框绑定到可空的布尔转换从空到真
【发布时间】:2011-07-15 21:36:38
【问题描述】:

我有一个复选框,其IsChecked 属性绑定到一个可为空的布尔值。当我的控件首次加载时,该值为 null 并且复选框显示为灰色。这就是我想要的。

当用户点击复选框时,它会进入 false/Unchecked 状态。

但是,99% 的时间用户会想要勾选复选框 - 这目前意味着双击复选框。

当用户第一次点击复选框时,如何使值从 null 变为 true?

【问题讨论】:

    标签: wpf binding checkbox


    【解决方案1】:

    我遇到了同样的问题并遇到了这个问题。这是一个迟到的回应,但我认为这是最好的解决方案:)

    IsThreeStateTargetNullValue 的帮助下,您可以完成此操作

     <CheckBox  IsThreeState="False" IsChecked="{Binding YOUR_NULLABLE_PROPERTY, TargetNullValue=false}" />
    

    唯一需要注意的是它会在 null 和 true 之间切换。永远不会有错误的值。

    【讨论】:

      【解决方案2】:

      你可以只修改绑定属性的setter来检查之前的值是否为null,如果是,将值设置为true。像这样的:

      public bool? MyBoolProperty 
      {
         get { return _myBoolProperty; }
         set 
         {
             _myBoolProperty = (_myBoolProperty != null || value == null) ? value : true;
             RaisePropertyChanged("MyBoolProperty");       
         }
      }
      

      绑定系统设置后会重新读取属性,所以新的值会被CheckBox反映。

      【讨论】:

      • 这也会影响尝试设置属性的代码,这是相当狡猾的。
      【解决方案3】:

      您可以处理 Click 事件并实现如下逻辑:

      private void CheckBox_Click(object sender, RoutedEventArgs e)
      {
        CheckBox cb = sender as CheckBox;
      
        switch (cb.IsChecked) 
        {
          case null:
            cb.IsChecked = false;
            break;
      
          case true:
            cb.IsChecked = true;
            break;
      
          case false:
            if (cb.IsThreeState) {
              cb.IsChecked = null;
            } else {
              cb.IsChecked = true;
            }
            break;
        }
      
        e.Handled = true;
      
      }
      

      【讨论】:

        【解决方案4】:

        我最近遇到了这个问题。我查看了这个问题的所有答案,但似乎没有一个适合我。当我在 ViewModel 中设置 IsChecked 等于 false 时,接受的答案是失败。我反编译 wpf 中的复选框。 如您所见,当您单击一个空的IsChecked 复选框时,IsChecked 属性将切换为 false。

        protected internal virtual void OnToggle()
        {
            bool? flag;
            if (this.IsChecked == true)
            {
                flag = (this.IsThreeState ? null : new bool?(false));
            }
            else
            {
                flag = new bool?(this.IsChecked.HasValue);
            }
            base.SetCurrentValueInternal(ToggleButton.IsCheckedProperty, flag);
        }
        

        所以你可以创建一个新类继承 CheckBox 并覆盖 OnToggle 方法,如下所示:

        protected override void OnToggle()
        {
           bool? flag;
           if (this.IsChecked == true)
           {
               flag = this.IsThreeState ? null : new bool?(false);
           }
           else 
               flag = true;
           // what a pity this method is internal
           // actually you can call this method by reflection
           base.SetCurrentValueInternal(ToggleButton.IsCheckedProperty, flag);
        }
        

        另一种方式是:

        protected override void OnToggle()
        {
            if (this.IsChecked == null)
                this.IsChecked = false;
            base.OnToggle();
        }
        

        【讨论】:

          【解决方案5】:

          最简单的方法是简单地处理click 事件并将控件设置为true(如果其当前状态为null),还可以选择设置flag 用于在首次单击后进行内部代码跟踪。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-10-14
            • 2012-03-11
            • 2014-01-25
            • 2015-04-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多