WPF Adorner+附加屬性 實現控件友好提示


標題太空泛,直接上圖

 

無論是在驗證啊,還是提示方面等一些右上角的角標之類的效果,我們會怎么做?

這里介紹一種稍微簡單一些的方法,利用附加屬性和Adorner來完成。

 

例如WPF自帶的控件上要加這樣的效果,首先繼承自原控件然后重寫是可以的,但是控件類型太多,重寫不過來。這個時候我們唯一能添加的只有附加屬性了。

利用附加屬性的屬性變更事件PropertyChangedCallBack,我們可以獲取到宿主對象即Button,然后就可以往Button上加入我們自定義的Adorner了。再添加一個附加屬性控制Adorner的顯示/隱藏,那么就很完美了,這樣每個控件只用設置兩個附加屬性就能擁有上面的效果。下面是核心代碼,

附加屬性

public class AdornerHelper
    {
        #region 是否有Adorner
        public static bool GetHasAdorner(DependencyObject obj)
        {
            return (bool)obj.GetValue(HasAdornerProperty);
        }

        public static void SetHasAdorner(DependencyObject obj, bool value)
        {
            obj.SetValue(HasAdornerProperty, value);
        }

        // Using a DependencyProperty as the backing store for HasAdorner.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HasAdornerProperty =
            DependencyProperty.RegisterAttached("HasAdorner", typeof(bool), typeof(AdornerHelper), new PropertyMetadata(false, PropertyChangedCallBack));

        private static void PropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                var element = d as Visual;

                if (element != null)
                {
                    var adornerLayer = AdornerLayer.GetAdornerLayer(element);

                    if (adornerLayer!=null)
                    {
                        adornerLayer.Add(new NotifyAdorner(element as UIElement)); 
                    }
                }
            }
        } 
        #endregion

        #region 是否顯示Adorner


        public static bool GetIsShowAdorner(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsShowAdornerProperty);
        }

        public static void SetIsShowAdorner(DependencyObject obj, bool value)
        {
            obj.SetValue(IsShowAdornerProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsShowAdorner.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsShowAdornerProperty =
            DependencyProperty.RegisterAttached("IsShowAdorner", typeof(bool), typeof(AdornerHelper), new PropertyMetadata(false,IsShowChangedCallBack));

        private static void IsShowChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as UIElement;

            if (element != null)
            {
                var adornerLayer = AdornerLayer.GetAdornerLayer(element);
                if (adornerLayer!=null)
                {
                    var adorners = adornerLayer.GetAdorners(element);
                    if (adorners != null && adorners.Count() != 0)
                    {
                        var adorner = adorners.FirstOrDefault() as NotifyAdorner;

                        if (adorner == null)
                        {
                            return;
                        }

                        if ((bool)e.NewValue)
                        {
                            adorner.ShowAdorner();
                        }
                        else
                        {
                            adorner.HideAdorner();
                        }
                    } 
                }
            }
        }

        #endregion
    }

然后是我們自定義的Adorner效果

public class NotifyAdorner : Adorner
    {
        private VisualCollection _visuals;
        private Canvas _grid;
        private Image _image;

        public NotifyAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            _visuals = new VisualCollection(this);
            _image=new Image()
            {
                Source = new BitmapImage(new Uri("Notify.png",UriKind.RelativeOrAbsolute)),
                Width = 25,
                Height = 25
            };

            _grid = new Canvas();
            _grid.Children.Add(_image);

            _visuals.Add(_grid);
        }

        public void ShowAdorner()
        {
            _image.Visibility = Visibility.Visible;
        }

        public void HideAdorner()
        {
            _image.Visibility = Visibility.Collapsed;
        }

        protected override int VisualChildrenCount
        {
            get
            {
                return _visuals.Count;
            }
        }

        protected override Visual GetVisualChild(int index)
        {
            return _visuals[index];
        }

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

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

            _image.Margin=new Thickness(finalSize.Width-12.5,-12.5,0,0);

            return base.ArrangeOverride(finalSize);
        }


    }


這里是源碼http://files.cnblogs.com/HelloMyWorld/AdornerSample.rar

大家看代碼就能懂了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM