【问题标题】:WPF Check box: Check changed handlingWPF 复选框:检查更改的处理
【发布时间】:2023-03-19 04:08:01
【问题描述】:

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

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

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

【问题讨论】:

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

标签: c# wpf checkbox


【解决方案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 事件处理程序,我关心的是“更改”信号。
        猜你喜欢
        • 1970-01-01
        • 2015-07-04
        • 1970-01-01
        • 2017-11-22
        • 2015-10-22
        • 1970-01-01
        • 1970-01-01
        • 2011-09-09
        • 2012-11-20
        相关资源
        最近更新 更多