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

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

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

上节课的应用,是为这节课的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,”的文章

猜你喜欢

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

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

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

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

你要他作甚?HasUpdateNotify  

发表评论

必填

选填

选填

必填

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

  查看权限

合肥科大智能常年招聘.NET,Java,Web前端,有想找想换工作的私聊我AY唯一QQ:875556003和AY交流

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

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

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

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

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

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

查看捐赠

AYUI7.X MVC教程 更新如下:

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

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

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

标签列表