A read-only CheckBox in C# WPF

后端 未结 11 2071
南方客
南方客 2020-12-06 04:37

I am having a tricky problem, I want some slightly unusual behaviour from a checkbox and can\'t seem to figure it out. Any suggestions would be most welcome. The behaviour I

11条回答
  •  庸人自扰
    2020-12-06 05:16

    I had a need for the AutoCheck functionality be off as well for a Checkbox/RadioButton, where I wanted to handle the Click event without having the control auto-check. I've tried various solutions here and on other threads and was unhappy with the results.

    So I dug into what WPF is doing (using Reflection), and I noticed:

    1. Both CheckBox & RadioButton inherit from the ToggleButton control primitive. Neither of them have a OnClick function.
    2. The ToggleButton inherits from the ButtonBase control primitive.
    3. The ToggleButton overrides the OnClick function and does: this.OnToggle(); base.OnClick();
    4. ButtonBase.OnClick does 'base.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent, this));'

    So basically, all I needed to do was override the OnClick event, don't call OnToggle, and do base.RaiseEvent

    Here's the complete code (note that this can easily be reworked to do RadioButtons as well):

    using System.Windows.Controls.Primitives;
    
    public class AutoCheckBox : CheckBox
    {
    
        private bool _autoCheck = false;
        public bool AutoCheck {
            get { return _autoCheck; }
            set { _autoCheck = value; }
        }
    
        protected override void OnClick()
        {
            if (_autoCheck) {
                base.OnClick();
            } else {
                base.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent, this));
            }
        }
    
    }
    

    I now have a CheckBox that doesn't auto-check, and still fires the Click event. Plus I can still subscribe to the Checked/Unchecked events and handle things there when I programmatically change the IsChecked property.

    One final note: unlike other solutions that do something like IsChecked != IsChecked in a Click event, this won't cause the Checked/Unchecked/Indeterminate events to fire until you programmatically set the IsChecked property.

提交回复
热议问题