WPF 复选框:检查更改的处理
Posted
技术标签:
【中文标题】WPF 复选框:检查更改的处理【英文标题】:WPF Check box: Check changed handling 【发布时间】:2013-03-06 23:50:31 【问题描述】:在 WPF 数据绑定中,我可以将 IsChecked 属性绑定到一些数据,例如用户设置,但我需要处理“CheckChanged”事件,我知道我可以分别处理 Checked、Unchecked事件,但是有什么方法可以在更改此值时得到通知?
<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"/>
对我来说,它同时触发 Check
和 Uncheck
。
【讨论】:
【参考方案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 复选框:检查更改的处理的主要内容,如果未能解决你的问题,请参考以下文章