当前位置:网站首页 / WPF / 正文

[ay的wpf]写给自己的wpf高级教程 [3]-adorner[2/4]

时间:2015年12月14日 | 作者 : aaronyang | 分类 : WPF | 浏览: 4244次 | 评论 3

上节课的应用,是为这节课的demo打下基础的

这节课我们要实现的是一个可以拖拽和调整的大小的adorner

在wpf移动控件,最简单的容器是Canvas,我们把外层的Grid换成Canvas

2015年12月14日16:59:34  www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任

<Window x:Class="WpfApplication7.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="Window_Loaded" 
        Title="www.ayjs.net ay讲解wpf的博客" Height="350" Width="525" WindowStartupLocation="CenterScreen">
    <Canvas x:Name="ddd" >
        <Rectangle Width="64" Height="64" x:Name="appstore" Canvas.Left="126" Canvas.Top="61">
            <Rectangle.Fill>
                <ImageBrush ImageSource="icon1.jpg"/>
            </Rectangle.Fill>
        </Rectangle>
    </Canvas>
</Window>

先看最终实现效果图:

6.gif

我新建了AyDragAdorner,这里是基本模板。

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;


namespace WpfApplication7
{
   public class AyDragAdorner : Adorner
    {



        VisualCollection visCollec;



        public AyDragAdorner(UIElement adorned)

            : base(adorned)
        {

            visCollec = new VisualCollection(this);


        }



        protected override Size ArrangeOverride(Size finalSize)
        {

         


            return finalSize;

        }



      



      



       

        protected override Visual GetVisualChild(int index)
        {

            return visCollec[index];

        }



        protected override int VisualChildrenCount
        {

            get
            {

                return visCollec.Count;

            }

        }



    }
}

关于Thumb控件

默认的样子

<Thumb Width="40" Height="40" Canvas.Left="284" Canvas.Top="72" ></Thumb>

blob.png

OK,我们后台创建,并后台指定模板

       private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var al = AdornerLayer.GetAdornerLayer(appstore);
            al.Add(new HasUpdateNotify(appstore, "5"));
            //al.Add(new AyDragAdorner(appstore));

            Thumb tb = new Thumb();
            tb.Width = 40;
            tb.Height = 40;
            tb.Background = Brushes.Blue;
            tb.Cursor = Cursors.ScrollE;
            tb.Template = new ControlTemplate(typeof(Thumb))

               {

                   VisualTree = GetFactory(new SolidColorBrush(Colors.Green))

               };
            Canvas.SetTop(tb, 72);
            Canvas.SetLeft(tb, 284);
            ddd.Children.Add(tb);

        }
        FrameworkElementFactory GetFactory(Brush back)
        {

            back.Opacity = 0.6;

            var fef = new FrameworkElementFactory(typeof(Ellipse));

            fef.SetValue(Ellipse.FillProperty, back);

            fef.SetValue(Ellipse.StrokeProperty, Brushes.Green);

            fef.SetValue(Ellipse.StrokeThicknessProperty, (double)1);

            return fef;

        }

blob.png

看下他的DragDelta事件,其实鼠标拖拽thumb走的时候,看似没动,其实移动位置已经动了

7.gif

2015年12月14日16:59:34  www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任

我们只需要通过这些值,调整绑定的 元素的宽高,由于,这个圆是跟宿主 相对布局的,所以宿主打了,自己的位置也就变了。

最终这个缩放和调整大小的装饰器代码如下:

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;


namespace WpfApplication7
{
   public class AyDragAdorner : Adorner
    {

        const double THUMB_SIZE = 12;

        const double MINIMAL_SIZE = 20;

        const double MOVE_OFFSET = 20;

        Thumb tl, tr, bl, br;

        Thumb mov;

        VisualCollection visCollec;



        public AyDragAdorner(UIElement adorned)

            : base(adorned)
        {

            visCollec = new VisualCollection(this);

            visCollec.Add(tl = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Left, VerticalAlignment.Top));

            visCollec.Add(tr = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Right, VerticalAlignment.Top));

            visCollec.Add(bl = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Left, VerticalAlignment.Bottom));

            visCollec.Add(br = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Right, VerticalAlignment.Bottom));

            visCollec.Add(mov = GetMoveThumb());

        }



        protected override Size ArrangeOverride(Size finalSize)
        {

            double offset = THUMB_SIZE / 2;

            Size sz = new Size(THUMB_SIZE, THUMB_SIZE);

            tl.Arrange(new Rect(new Point(-offset, -offset), sz));

            tr.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, -offset), sz));

            bl.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height - offset), sz));

            br.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height - offset), sz));

            mov.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - THUMB_SIZE / 2, -MOVE_OFFSET), sz));



            return finalSize;

        }



        void Resize(FrameworkElement ff)
        {

            if (Double.IsNaN(ff.Width))

                ff.Width = ff.RenderSize.Width;

            if (Double.IsNaN(ff.Height))

                ff.Height = ff.RenderSize.Height;

        }



        Thumb GetMoveThumb()
        {

            var thumb = new Thumb()

            {

                Width = THUMB_SIZE,

                Height = THUMB_SIZE,

                Cursor = Cursors.SizeAll,

                Template = new ControlTemplate(typeof(Thumb))

                {

                    VisualTree = GetFactory(GetMoveEllipseBack())

                }

            };

            thumb.DragDelta += (s, e) =>
            {

                var element = AdornedElement as FrameworkElement;

                if (element == null)

                    return;



                Canvas.SetLeft(element, Canvas.GetLeft(element) + e.HorizontalChange);

                Canvas.SetTop(element, Canvas.GetTop(element) + e.VerticalChange);

            };

            return thumb;

        }



        Thumb GetResizeThumb(Cursor cur, HorizontalAlignment hor, VerticalAlignment ver)
        {

            var thumb = new Thumb()

            {

                Background = Brushes.Red,

                Width = THUMB_SIZE,

                Height = THUMB_SIZE,

                HorizontalAlignment = hor,

                VerticalAlignment = ver,

                Cursor = cur,

                Template = new ControlTemplate(typeof(Thumb))

                {

                    VisualTree = GetFactory(new SolidColorBrush(Colors.Green))

                }

            };

            thumb.DragDelta += (s, e) =>
            {

                var element = AdornedElement as FrameworkElement;

                if (element == null)

                    return;



                Resize(element);



                switch (thumb.VerticalAlignment)
                {

                    case VerticalAlignment.Bottom:

                        if (element.Height + e.VerticalChange > MINIMAL_SIZE)
                        {

                            element.Height += e.VerticalChange;

                        }

                        break;

                    case VerticalAlignment.Top:

                        if (element.Height - e.VerticalChange > MINIMAL_SIZE)
                        {

                            element.Height -= e.VerticalChange;

                            Canvas.SetTop(element, Canvas.GetTop(element) + e.VerticalChange);

                        }

                        break;

                }

                switch (thumb.HorizontalAlignment)
                {

                    case HorizontalAlignment.Left:

                        if (element.Width - e.HorizontalChange > MINIMAL_SIZE)
                        {

                            element.Width -= e.HorizontalChange;

                            Canvas.SetLeft(element, Canvas.GetLeft(element) + e.HorizontalChange);

                        }

                        break;

                    case HorizontalAlignment.Right:

                        if (element.Width + e.HorizontalChange > MINIMAL_SIZE)
                        {

                            element.Width += e.HorizontalChange;

                        }

                        break;

                }



                e.Handled = true;

            };

            return thumb;

        }



        Brush GetMoveEllipseBack()
        {

            string lan = "M 0,5 h 10 M 5,0 v 10";

            var converter = TypeDescriptor.GetConverter(typeof(Geometry));

            var geometry = (Geometry)converter.ConvertFrom(lan);

            TileBrush bsh = new DrawingBrush(new GeometryDrawing(Brushes.Transparent, new Pen(Brushes.Green, 2), geometry));

            bsh.Stretch = Stretch.Fill;

            return bsh;

        }



        FrameworkElementFactory GetFactory(Brush back)
        {

            back.Opacity = 0.6;

            var fef = new FrameworkElementFactory(typeof(Ellipse));

            fef.SetValue(Ellipse.FillProperty, back);

            fef.SetValue(Ellipse.StrokeProperty, Brushes.Green);

            fef.SetValue(Ellipse.StrokeThicknessProperty, (double)1);

            return fef;

        }



        protected override Visual GetVisualChild(int index)
        {

            return visCollec[index];

        }



        protected override int VisualChildrenCount
        {

            get
            {

                return visCollec.Count;

            }

        }



    }
}

使用如下:

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var al = AdornerLayer.GetAdornerLayer(appstore);
            al.Add(new HasUpdateNotify(appstore, "5"));
            al.Add(new AyDragAdorner(appstore));
        }

效果如上,这里不演示了。到此结贴



2015年12月14日16:59:34  www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任

推荐您阅读更多有关于“WPF4.5,”的文章

猜你喜欢

已有3位网友发表了看法:

1#小鸭子666  2020-06-24 10:17:33 回复该评论

我一直一直以来想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说 想对你说   真棒。

2#访客  2019-08-13 16:12:09 回复该评论

HasUpdateNotify  这个类是什么啊?教程里没有 啊。

2#小鸭子666  2020-06-24 10:18:15 回复该评论

你要他作甚?HasUpdateNotify  

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

抖音号:wpfui,可以看到我的很多作品效果

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF,目前工作繁忙,不接任何活

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

兼容XP到win10,vs2015/2017/2019,最新AYUI:7.6.5.5

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表