zoukankan      html  css  js  c++  java
  • Adorner 装饰器

    装饰器 Adorner

    装饰器是WPF中较为常用的技术之一,也是不同于XAML的技术。

    较为特殊。

    特殊于装饰器全部由C#构成,不同于ControlTenmpate和Style的元素。

    装饰器在某些方面能够简化前两者的代码量。

    现在简单的说一下装饰器的入门用法(通常用法和附加属性一起使用

    Adorner是一个抽象类。

    由于显示装饰器的方式有两种

    1. 直接装载现有WPF控件

    2. 绘制控件


    直接装载现有控件:

             这种方法需要重载四个Adorner方法

    • GetVisualChild //获取Visual的子控件索引
    • ArrangeOverride //确定装饰器的定位
    • MeasureOverride //确定装饰器要约束道德大小
    • VisualChildrenCount//获取VisualCollection的集合数量

    重写之后就是

    编写 私有的VsualCollection来存储你要装载的控件。 

    然后利用MeasureOverride和ArrangeOverride这两个方法来进行定位和约束大小。

    下面的代码是 可以随时更新内容的装饰器

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Media;
    using System.Windows.Shapes;
    
    namespace 装饰器
    {
        public class TestAdorner : Adorner
        {
    
            private Grid _Grid;
            private Ellipse _Ellipse;
            private TextBlock _TextBlock;
            private VisualCollection collection;
            private UIElement _UIElement;
    
            public void UPDATE(string Text)
            {
                var grid = collection[0] as Grid;
    
                (grid.Children[1] as TextBlock).Text=Text;
    
            }
            public TestAdorner(UIElement adornedElement) : base(adornedElement)
            {
                collection = new VisualCollection(this);
    
                _Grid = new Grid()
                {
                    Width=20
                    ,
                    Height=20
                    
                };
    _Ellipse
    = new Ellipse() { Fill = new SolidColorBrush(Colors.Red) };
    _TextBlock
    = new TextBlock() { HorizontalAlignment = HorizontalAlignment.Center , VerticalAlignment = VerticalAlignment.Center , FontSize=15 }; _Grid.Children.Add(_Ellipse); _Grid.Children.Add(_TextBlock); collection.Add(_Grid); _UIElement = adornedElement; } protected override int VisualChildrenCount => collection.Count; protected override Visual GetVisualChild(int index) => collection[index]; protected override Size MeasureOverride(Size constraint) => base.MeasureOverride(constraint); protected override Size ArrangeOverride(Size finalSize) { _Grid.Arrange(new Rect(finalSize));
    _Grid.Margin
    = new Thickness((_UIElement as Button).ActualWidth-30, 0, 0, (_UIElement as Button).ActualHeight-30);
    return base.ArrangeOverride(finalSize); } } }

    XAML页面

        <Grid>
            <Button x:Name="TestBtn" Content="选中" Loaded="A_Loaded"  Height="100" Width="300"/>         
        </Grid>

    CS页面

    namespace 装饰器
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            AdornerLayer layer;
    
            DispatcherTimer timer;
    
            public MainWindow()
            {
                InitializeComponent();
    timer
    = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };
    timer.Tick
    += Timer_Tick; }

    private void Timer_Tick(object sender, EventArgs e) { if (i == 1000) timer.Stop();
    var b= layer.GetAdorners(TestBtn) ?? null;
    if(b!=null) { var k=b[0] as TestAdorner;
    k.UPDATE(i.ToString()); }
    else { var j = new TestAdorner(TestBtn);
    j.UPDATE(
    0.ToString());
    layer.Add(j); } i
    ++; } int i = 0; private void A_Loaded(object sender, RoutedEventArgs e) {
    layer
    = AdornerLayer.GetAdornerLayer(TestBtn);
    timer.Start();
    } } }

    效果图


    绘制控件

    绘制需要重载一个方法就好了

    •  OnRender//绘制控件

    不过值得注意的是,绘制方式无法更新。至少我是不会。

    现在给出代码

    namespace 装饰器
    {
        public class TestAdornerOnRender : Adorner
        {
    
            public TestAdornerOnRender(UIElement adornedElement) : base(adornedElement) { }
    
    
            protected override void OnRender(DrawingContext drawingContext)
            {
    
                FormattedText t = new FormattedText(
                 "!!!!!",
                 CultureInfo.InstalledUICulture,
                 FlowDirection.LeftToRight,
                 new Typeface("微软雅黑"),
                 15, new SolidColorBrush(Colors.Red)
                );
                drawingContext.DrawText(t, new Point(270, 0));
                base.OnRender(drawingContext);
            }
    
    
        }
    }

    xaml页面

    <Grid>
            <Button x:Name="TestBtn" Content="选中" Loaded="A_Loaded"  Height="100" Width="300">
                
            </Button>
        </Grid>

    cs 页面

     private void A_Loaded(object sender, RoutedEventArgs e)
            {
               var  layer = AdornerLayer.GetAdornerLayer(TestBtn);
    
                layer.Add(new TestAdornerOnRender(TestBtn));
                
              
            }

    截图

  • 相关阅读:
    Swift和OC混编
    Swift逃逸闭包之见解
    百度地图集成
    hitTest和pointInside和CGRectContainsPoint
    Bitcode问题
    ReactiveCocoa常用方法
    iOS之图文混排
    tableview cell添加3D动画
    ReactiveCocoa总结
    Math类常用方法(Java)
  • 原文地址:https://www.cnblogs.com/T-ARF/p/10125454.html
Copyright © 2011-2022 走看看