【问题标题】:Recognise when CheckBox_Checked event is fired cause of binding识别何时触发 CheckBox_Checked 事件是绑定的原因
【发布时间】:2020-09-15 15:41:34
【问题描述】:

如果以前有人问过这个问题,我深表歉意,但我找不到任何有用的东西。

我有以下课程

public class NumberOfInterest
{
    public bool HasChanged { get; set; } = false;
    public bool Prop1 { get; set; }
    public bool Prop2 { get; set; }
    ---
}

在我的用户控件中,我有一个 DataGrid 用作项目源 ObservableCollection<NumberOfInterest>。在这个网格中,我有 2 个CheckBox 列分别绑定到 Prop1 和 Prop2

最后,每个NumberOfInterest 的属性HasChanged 应在其初始状态发生变化(即Prop1 或Prop2 变化)时设置为true

属性HasChanged在CanExecute事件中的Command中使用方式如下

    public ICommand Save
    {
        get
        {
            save = new RelayCommand(() => SaveChanges(), () => NumbSource.Any(x => x.HasChanged));
            return save;
        }
    }

复选框以下列方式使用事件 CheckBox_Checked

    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        CheckBox c = sender as CheckBox;
        if (!(c.DataContext is NumberOfInterest n))
            return;
        n.HasChanged = true;
        n.Prop1 = c.IsChecked.Value;
    }

Prop2 也有类似的

问题在于,如果我的项目源中的元素将 2 Prop1 或 Prop2 中的任何一个默认设置为 true,则 HasChanged 会自动设置为 true。

我想找到一种方法来触发CheckBox_Checked 事件,只有在用户控件处于用户处置状态后(即用户可以对其进行迭代并加载所有内容)。

我尝试设置 Loaded 和 Initialized 来设置本地布尔值,但这些事件在项目源实际设置之前触发

我还在复选框绑定中尝试了 Mode = "OneWayToSource",但这首先会阻止复选框设置为正确的状态

【问题讨论】:

    标签: c# wpf checkbox


    【解决方案1】:

    这应该可行:

    n.HasChanged = n.Prop1 != c.IsChecked.Value;
    n.Prop1 = c.IsChecked.Value;
    

    或者:

    if (c.DataContext is NumberOfInterest n &&
        n.Prop1 != c.IsChecked.Value)
    {
        n.HasChanged = true;
        n.Prop1 = c.IsChecked.Value;
    }
    

    【讨论】:

    • 我更正了自己。起初我认为它有效,但后来我意识到它实际上并非如此。绑定 n.Prop1 的原因不能与 c.IsChecked.Value 不同,因为复选框已将 IsChecked 属性绑定到 Prop1
    【解决方案2】:

    为什么不在NumberOfInterest 类中处理这个而不是在视图中处理Checked 事件?:

    public class NumberOfInterest
    {
        public bool HasChanged { get; set; } = false;
    
        private bool _prop1;
        public bool Prop1
        {
            get { return _prop1; }
            set
            {
                if (value != _prop1)
                {
                    _prop1 = value;
                    HasChanged = true;
                }
            }
        }
    
        private bool _prop2;
        public bool Prop2
        {
            get { return _prop2; }
            set
            { 
                if(value != _prop2)
                {
                    _prop2 = value;
                    HasChanged = true;
                }
            }
        }
    }
    

    如果您最初设置了Prop1 和Prop2 属性(而不是设置支持字段),您还应该在完成此操作后将HasChanged 设置为false。

    更好的方法是定义一个执行初始化的自定义构造函数:

    public class NumberOfInterest
    {
        public bool HasChanged { get; private set; } = false;
    
        public NumberOfInterest(bool prop1, bool prop2)
        {
            _prop1 = prop1;
            _prop2 = prop2;
        }
    
        private bool _prop1;
        public bool Prop1
        {
            get { return _prop1; }
            set
            {
                if (value != _prop1)
                {
                    _prop1 = value;
                    HasChanged = true;
                }
            }
        }
    
        private bool _prop2;
        public bool Prop2
        {
            get { return _prop2; }
            set
            { 
                if(value != _prop2)
                {
                    _prop2 = value;
                    HasChanged = true;
                }
            }
        }
    }
    

    然后您还可以将HasChanged 属性的设置器设为私有。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多