验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

C#中wpf怎么利用附加属性实现界面上定义装饰器

阅读:442 来源:乙速云 作者:代码code

C#中wpf怎么利用附加属性实现界面上定义装饰器

      前言

      装饰器是wpf中可以浮在控件上面的一种组件,我们通常可以用来实现一些诸如控件拖动点、提示框、自定义鼠标等界面功能。装饰器的用法其实还是比较复杂的,几乎需要完全再cs中编写所有代码,对于样式要求较高的情况下,完全在cs中些控件的样式是比较困难的。为了改变这种状况,我们可以使用附加属性将装饰器的逻辑封装,提供一个可以在界面上定义的属性。

      一、如何实现

      1、实现装饰器

      由于Adorner是一个抽象类不能直接实现,所有我们需要定义一个子类实现并它。

      class NormalAdorner : Adorner
      {
          /// 
          /// 构造方法
          /// 
          /// 被添加装饰器的元素
          /// 放到装饰器中的元素
          public NormalAdorner(UIElement adornedElement, UIElement child) : base(adornedElement);
          protected override Visual GetVisualChild(int index);
          protected override int VisualChildrenCount;
          protected override Size ArrangeOverride(Size finalSize);
      }

      2、定义附加属性

      通过propa快捷定义一个名称为AdornerContent的附加属性其类型UIElement。

      public static UIElementGetAdornerContent(DependencyObject obj)
      {
          return (UIElement)obj.GetValue(AdornerContent);
      }
      public static void SetAdornerContent(DependencyObject obj, Control value)
      {
          obj.SetValue(AdornerContent, value);
      }
      // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty AdornerContent =
          DependencyProperty.RegisterAttached("AdornerContent", typeof(UIElement), typeof(AdornerHelper), new PropertyMetadata(null));

      3、加入装饰层

      在附加属性改变事件中,进行装饰层的添加。

      public void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
          var c = d as UIElement;
          //获取装饰层
          var layer = AdornerLayer.GetAdornerLayer(c);
          //添加装饰器
           layer.Add(new NormalAdorner(c, (UIElement)e.NewValue));
      }

      二、完整代码

      AdornerHelper.cs

      using System;
      using System.Windows;
      using System.Windows.Documents;
      using System.Windows.Media;
      namespace AC
      {
          internal class AdornerHelper
          {
              public static UIElement GetAdornerContent(DependencyObject obj)
              {
                  return (UIElement)obj.GetValue(AdornerContent);
              }
              public static void SetAdornerContent(DependencyObject obj, UIElement value)
              {
                  obj.SetValue(AdornerContent, value);
              }
              // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
              public static readonly DependencyProperty AdornerContent =
                  DependencyProperty.RegisterAttached("AdornerContent", typeof(UIElement), typeof(AdornerHelper), new PropertyMetadata(null, (d, e) =>
                  {
                      var c = d as FrameworkElement;
                      if (c == null)
                          return;
                      var adronerContent = e.NewValue as UIElement;
                      if (!c.IsLoaded)
                      {
                          if (adronerContent != null)
                          {
                              RoutedEventHandler l = null;
                              l = (s, E) =>
                              {
                                  var content = GetAdornerContent(c);
                                  if (content != null)
                                  {
                                      var layer = AdornerLayer.GetAdornerLayer(c);
                                      if (layer == null)
                                          throw new Exception("获取控件装饰层失败,控件可能没有装饰层!");
                                      layer.Add(new NormalAdorner((UIElement)c, (UIElement)e.NewValue));
                                  }
                                  c.Loaded -= l;
                              };
                              c.Loaded += l;
                          }
                      }
                      else
                      {
                          var layer = AdornerLayer.GetAdornerLayer(d as Visual);
                          if (layer == null)
                              throw new Exception("获取控件装饰层失败,控件可能没有装饰层!");
                          if (e.OldValue != null)
                          {
      
                              var adorners = layer.GetAdorners(c);
                              foreach (var i in adorners)
                              {
                                  if (i is NormalAdorner)
                                  {
                                      var na = i as NormalAdorner;
                                      if (na.Child == e.OldValue)
                                      {
                                          layer.Remove(i);
                                          break;
                                      }
                                  }
                              }
                          }
                          if (adronerContent != null)
                          {
                              layer.Add(new NormalAdorner((UIElement)c, (UIElement)e.NewValue));
                          }
                      }
                  }));
      
              class NormalAdorner : Adorner
              {
                  UIElement _child;
                  /// 
                  /// 构造方法
                  /// 
                  /// 被添加装饰器的元素
                  /// 放到装饰器中的元素
                  public NormalAdorner(UIElement adornedElement, UIElement child) : base(adornedElement)
                  {
                      _child = child;
                      AddVisualChild(child);
                  }
                  public UIElement Child { get { return _child; } }
                  protected override Visual GetVisualChild(int index)
                  {
                      return _child;
                  }
                  protected override int VisualChildrenCount
                  {
                      get
                      {
                          return 1;
                      }
                  }
                  protected override Size ArrangeOverride(Size finalSize)
                  {
                      _child.Arrange(new Rect(new Point(0, 0), finalSize));
                      return finalSize;
                  }
              }
          }
      }

      三、使用示例

      
          
              
                   
                  
                      
                          
                              
                                  
                                      
                                          
                                              
                                          
                                      
                                  
                              
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                          
                      
                  
              
          
      

      效果预览

      C#中wpf怎么利用附加属性实现界面上定义装饰器

    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>