WPF 复选框:检查更改的处理

Posted

技术标签:

【中文标题】WPF 复选框:检查更改的处理【英文标题】:WPF Check box: Check changed handling 【发布时间】:2013-03-06 23:50:31 【问题描述】:

在 WPF 数据绑定中,我可以将 IsChecked 属性绑定到一些数据,例如用户设置,但我需要处理“CheckChanged”事件,我知道我可以分别处理 CheckedUnchecked事件,但是有什么方法可以在更改此值时得到通知?

<CheckBox Content="Case Sensitive" IsChecked="Binding bSearchCaseSensitive,
          Source=x:Static Properties:Settings.Default" />

注意:我不在乎它是选中还是未选中。我只想在更改时收到通知。

【问题讨论】:

你要那个干什么?为什么不将IsChecked 属性绑定到 ViewModel 中的某个东西并对该属性做出反应? UI 不是数据。 已经绑定到用户设置。 UI不是数据,这与提出的问题有关吗? 我的观点是,如果 ViewModel 需要知道什么时候发生了变化,你应该真正将它绑定到 ViewModel,而不是静态的东西,然后你可以从 VM 中更改静态值. 我不想改变值,我想处理改变的事件并做其他事情,例如显示一个消息框。你有什么建议来挂钩这个事件吗? 表示感谢。但我想看看是否有更简洁的解决方案。 【参考方案1】:

我发现使用 MVVM 模式处理已检查/未检查事件的一种简单而正确的方法如下,使用 Caliburn.Micro :

 <CheckBox IsChecked="Binding IsCheckedBooleanProperty" Content="DynamicResource DisplayContent" cal:Message.Attach="[Event Checked] = [Action CheckBoxClicked()]; [Event Unchecked] = [Action CheckBoxClicked()]" />

并在 ViewModel 中实现一个方法 CheckBoxClicked() 来做你想做的事情。

【讨论】:

【参考方案2】:

作为一个复选框单击 = 一个复选框更改以下内容也将起作用:

<CheckBox Click="CheckBox_Click" />
private void CheckBox_Click(object sender, RoutedEventArgs e)

    // ... do some stuff

它具有在IsThreeState="True" 时工作的额外优势,而仅处理 Checked 和 Unchecked 则不行。

【讨论】:

如果复选框被禁用但您单击它会发生什么?我猜这个事件仍然会触发,大多数时候这不是我们想要的行为 这不应该发生。如果它被禁用,点击事件也将被禁用。 对于禁用控件和使用键盘时,它确实具有正确的行为。此事件与一般“状态更改”事件之间的显着区别在于,以编程方式更改复选框时不会触发该事件。【参考方案3】:

我知道这是一个老问题,但是如果使用 MVVM,只绑定到 Command 怎么样?

例如:

<CheckBox Content="Case Sensitive" Command="Binding bSearchCaseSensitive"/>

对我来说,它同时触发 CheckUncheck

【讨论】:

【参考方案4】:

可以分别处理已检查和未检查的事件并不意味着您必须。如果您不想遵循 MVVM 模式,您可以简单地将相同的处理程序附加到两个事件,然后您就有了更改信号:

<CheckBox Checked="CheckBoxChanged" Unchecked="CheckBoxChanged"/>

在代码隐藏中;

private void CheckBoxChanged(object sender, RoutedEventArgs e)

  MessageBox.Show("Eureka, it changed!");

请注意,出于某种原因,WPF 强烈鼓励使用 INotifyPropertyChanged 和/或 DependencyProperties 的 MVVM 模式。这是行之有效的事情,而不是我想要鼓励的良好编程习惯。

【讨论】:

【参考方案5】:

我把这个放在答案中是因为评论太长了:

如果您需要 VM 知道 CheckBox 何时更改,您应该真正将 CheckBox 绑定到 VM,而不是静态值:

public class ViewModel

    private bool _caseSensitive;
    public bool CaseSensitive
    
        get  return _caseSensitive; 
        set
        
            _caseSensitive = value;
            NotifyPropertyChange(() => CaseSensitive);

            Settings.Default.bSearchCaseSensitive = value;
        
    

XAML:

<CheckBox Content="Case Sensitive" IsChecked="Binding CaseSensitive"/>

【讨论】:

@HighScore,谢谢,这是一个解决方案,但对我的情况来说太过分了。我不想诉诸INotifyPropertyChanged,它太麻烦了。 :) @David 什么?你如何处理没有INotifyPropertyChanged 的 WPF 双向绑定?此外,这与示例无关,它之所以存在,是因为它是 ViewModel 属性。如果您删除它,我的示例就可以正常工作。 确实,这是双向绑定。该设置可以读写,可惜没有通知我设置器更改。 @RalfdeKleine,我不知道你的评论有什么意义,正如其他人已经指出的那样。 @RalfdeKleine,我从不这么说。【参考方案6】:

Checked 事件呢?将其与 AttachedCommandBehaviors 或类似的东西结合使用,以及 DelegateCommand 以在每次调用该事件时在您的视图模型中触发一个函数。

【讨论】:

正如问题中所述,我不想使用 Checked/Unchecked 事件处理程序,我关心的是“更改”信号。

以上是关于WPF 复选框:检查更改的处理的主要内容,如果未能解决你的问题,请参考以下文章

WPF 复选框自定义样式检查消失

WPF点击标签更改复选框isChecked属性[重复]

在列表框中选中复选框时更改文本框的颜色 c# wpf

带有复选框的 C# WPF 目录树视图:检查构建项目失败,PropertyChanged 为空

如何在 android 复选框检查更改上接收事件?

循环检查网格中的复选框并获取标签值WPF c#