WPF 自定義控件之禁用時的鼠標樣式

廢話不多說,客官先看圖

 在WPF 中,控件禁用的時候,雖然可以利用觸發器去修改控件的本身的樣式,但是,鼠標樣式Cursor確不會生效。可是產品和UI怎麼會放過你呢,畢竟web控件可是可以改的。

解決方案:

利用裝飾器和附加屬性,完美繼承原先的樣式和邏輯,而且對所有控件都有效;

裝飾器代碼:

思路很簡單,就是給控件添加一個蒙層,禁用的時候,鼠標其實是位於在蒙層上;

public class UnableAdorner : Adorner
    {
        private readonly VisualCollection _collection;

        private readonly Grid _grid;
        private Border _border;

        protected override int VisualChildrenCount => _collection.Count;

        protected override Visual GetVisualChild(int index) => _collection[index];

        public UnableAdorner(UIElement uIElement) : base(uIElement) {

            _collection = new VisualCollection(this);
            _grid = new Grid();
            _border = new Border()
            {
                Background = Brushes.Transparent,
                Cursor = (Cursor)TryFindResource("UnableCursor") ?? Cursors.No,
            };

            _grid.Children.Add(_border);
            _collection.Add(_grid);
        }

        public void SetEnable(bool isEnable) {
            _border.IsHitTestVisible = !isEnable;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            return base.MeasureOverride(constraint);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _grid.Arrange(new Rect(finalSize));
            return base.ArrangeOverride(finalSize);

        }
    }

附加屬性:

利用附加屬性,給控件添加對應的裝飾器

    public class Assists
    {
        #region 控件IsEnable 屬性,用於重寫IsEnable樣式
        public static bool GetIsEnable(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsEnableProperty);
        }

        public static void SetIsEnable(DependencyObject obj, bool value)
        {
            obj.SetValue(IsEnableProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsEnable.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsEnableProperty =
            DependencyProperty.RegisterAttached("IsEnable", typeof(bool), typeof(Assists), new PropertyMetadata(true, IsEnablePropertyChanged));

        private static void IsEnablePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is UIElement uIElement) {
                var adorner = (UnableAdorner)uIElement.GetOrAddAdorner(typeof(UnableAdorner));
                adorner.SetEnable((bool)e.NewValue);
            }
        }
        #endregion


    }

注意:裝飾器使用的時候 需要AdornerDecorator;

源碼地址:https://github.com/Super0Lan/ControlDesign

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章