zoukankan      html  css  js  c++  java
  • 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

    大家看代码就能懂了

  • 相关阅读:
    ApiKernel
    ApiUser
    BringWindowToTop完美激活窗口与置顶
    poj2486 Apple Tree【区间dp】
    HYSBZ1588 营业额统计【Splay】
    hdu5115 Dire Wolf【区间dp】
    poj1144 Network【tarjan求割点】
    poj1236 Network of Schools【强连通分量(tarjan)缩点】
    poj2342 Anniversary party【树形dp】
    poj2449 Remmarguts' Date【A*算法】
  • 原文地址:https://www.cnblogs.com/HelloMyWorld/p/3965177.html
Copyright © 2011-2022 走看看