RadioButton取消选中(附加属性)

多个选择只能选中一个并且还可以取消选择的需求,这里肯定是用到RadioButton,但是RadioButton又不支持取消选中。

方法一:继承RadioButton的自定义控件,这种方法可以实现,但是很费时

方法二:就是附加属性了

这里有个简单的口诀:要造新车,用自定义控件,要给旧车加装新功能,用附加属性

 

直接贴代码

    public class RadioButtonAttached
    {
        // 定义一个附加属性,用于启用/禁用取消选中功能
        public static readonly DependencyProperty CanUncheckProperty =
            DependencyProperty.RegisterAttached(
                "CanUncheck",
                typeof(bool),
                typeof(RadioButtonAttached),
                new PropertyMetadata(false, OnCanUncheckChanged));

        public static void SetCanUncheck(RadioButton element, bool value)
        {
            element.SetValue(CanUncheckProperty, value);
        }
        public static bool GetCanUncheck(RadioButton element)
        {
            return (bool)element.GetValue(CanUncheckProperty);
        }

        private static void OnCanUncheckChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is RadioButton radioButton)
            {
                // 移除旧事件处理程序以避免重复订阅
                radioButton.PreviewMouseDown -= RadioButton_PreviewMouseDown;
                radioButton.Checked -= RadioButton_Checked;
                radioButton.Unchecked -= RadioButton_Unchecked;

                if ((bool)e.NewValue)
                {
                    // 当属性设置为True时,订阅事件
                    radioButton.PreviewMouseDown += RadioButton_PreviewMouseDown;
                    radioButton.Checked += RadioButton_Checked;
                    radioButton.Unchecked += RadioButton_Unchecked;
                }
            }
        }

        // 使用RadioButton的Tag属性来存储其上一次的选中状态
        private static void RadioButton_Checked(object sender, RoutedEventArgs e)
        {
            if (sender is RadioButton rb)
            {
                rb.Tag = true; 
            }
        }
        private static void RadioButton_Unchecked(object sender, RoutedEventArgs e)
        {
            if (sender is RadioButton rb)
            {
                rb.Tag = false; 
            }
        }
        private static void RadioButton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var rb = sender as RadioButton;
            if (rb == null) return;

            // 获取上一次的状态(若Tag为空,则默认为false)
            bool lastChecked = (rb.Tag is bool tagValue) ? tagValue : false;

            if (lastChecked)
            {
                // 如果上一次是选中的,则本次点击取消选中
                rb.IsChecked = false;
            }
            else
            {
                // 如果上一次是未选中的,则本次点击选中
                rb.IsChecked = true;
            }
            // 阻止事件继续传递,避免内部逻辑干扰
            e.Handled = true;
        }
    }

  

RadioButton button = new RadioButton();
RadioButtonAttached.SetCanUncheck(button, true);

    当启用取消选中时,控件就会注册选中事件和取消选中事件,每次操作时记录当前的选中状态,在点击时判断当前选中状态,如果是选中则取消选中并中断事件传递。

 

posted @ 2025-12-10 14:58  会飞的飞机  阅读(0)  评论(0)    收藏  举报