1

我面临以下问题:对于 WPF 中的复选框,我需要知道何时尝试更改复选框的状态,即:

  • 如果用户单击了复选框 - 触发事件,
  • 如果复选框 IsChecked 属性被赋予一个新值 - 触发一个事件,
  • 如果复选框 IsChecked 属性被赋予与它已经拥有的相同的值 - 触发一个事件。

这种结构将用于控制嵌入式设备的软件。无法请求该设备的状态,只能告诉该设备进入某个状态。如果设备处于某种状态,再告诉它进入这个状态并没有什么坏处。因此,我的请求。

到目前为止,我已经提出了以下解决方案:编写一个派生自 CheckBox 的新类,但通过以下方式重新定义 IsChecked 属性:

public class ExtendedCheckBox : CheckBox
{
    public class IsCheckedAssignedEventArgs : RoutedEventArgs
    {
        public bool? prevState { get; set; }
        public bool? newState { get; set; }
        public IsCheckedAssignedEventArgs(bool? prevState, bool? newState)
        {
            this.prevState = prevState;
            this.newState = newState;
        }
    }

    public event EventHandler IsCheckedAssigned = delegate { };

    public new bool? IsChecked
    {
        get
        {
            return base.IsChecked;
        }

        set
        {
            this.IsCheckedAssigned(this, new IsCheckedAssignedEventArgs(this.IsChecked, value));
            base.IsChecked = value;
        }
    }
}

只有以编程方式分配 IsChecked 属性时,它才能正常工作。单击 CheckBox 时,不会触发该事件。

第一个问题是 - 这是解决我的问题的正确方法吗?如果是,如何使它适用于我需要的所有情况?如果不是,有什么更好的方法?

提前感谢您的任何想法。

4

4 回答 4

2

IsChecked 属性CheckBox是一个DependancyProperty. 只是在它上面创建一个新的包装器不会通过 UI 更新它,因为 WPF 引擎将调用GetValue() 和SetValue() 来获取和设置它的值,而不是你的属性包装器。

如果您想知道 IsChecked 是否已更改,则可以通过在类中添加以下代码来覆盖 IsCheckedProperty 的 propertymeta 数据。

    static ExtendedCheckBox ()
    {
        IsCheckedProperty.OverrideMetadata(typeof(ExtendedCheckBox ), new FrameworkPropertyMetadata(null , new CoerceValueCallback(IsCheckedCoerced)));
    }

    private static object IsCheckedCoerced(DependencyObject obj, object value)
    {
        var myCheckBox = obj as ExtendedCheckBox ;

        if (myCheckBox != null)
        {
            myCheckBox.IsCheckedAssigned(myCheckBox, new IsCheckedAssignedEventArgs(myCheckBox.IsChecked, (bool)value));
        }
        return value;
    }
于 2013-10-23T09:46:24.490 回答
1

如果您对属性 IsChecked 进行数据绑定,则每次更改时都会在绑定目标上设置该值

于 2013-10-23T09:46:08.150 回答
0

我在我的项目中使用类似于下面的复选框

<CheckBox Name="chkExist" Grid.Column="1" Grid.Row="0" Content="Existing settings" VerticalAlignment="Center" IsChecked="{Binding IsExistingSetting, Mode=TwoWay}"></CheckBox>

bool isExistingSetting;

public bool IsExistingSetting
{
  get { return isExistingSetting; }
  set
  {
    if (value != isExistingSetting)
    {
     //calling one method as per my business. Method(value);
      isExistingSetting= value;
      OnPropertyChanged("IsChecked");
     }
    }
 }
 private void Method(bool isValue)
 {
  if(isValue)
  {
    // do something...
  }
  else
  {
   // do something...
  }
}
于 2013-10-23T10:03:15.017 回答
0

覆盖 OnClick ; 您班级中的 OnChecked 和 OnUnchecked 事件并引发您的新事件;

于 2013-10-23T10:06:41.483 回答