wpf页面编辑器原理

原创 2016年06月02日 10:36:12

wpf实现页面编辑器,运行时拖拽控件大小,与修改控件位置,原理是使用装饰器来做,并且禁用掉控件的IsHittestVisiable属性就可以实现编辑控件位置与大小了,装饰器adornor如下:

 class ResizeMoveAdorner : Adorner
    {
        const double THUMB_SIZE = 8;
        const double MINIMAL_SIZE = 20;
        const double MOVE_OFFSET = 10;
        const double THUMB_BORDER_THICKNESS = 4;
       
        Thumb tl, tr, bl, br;
        Thumb leftThumb, topThumb, rightThumb, bottomThumb;
        Thumb mov;
        VisualCollection visCollec;

        public ResizeMoveAdorner(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(leftThumb = GetResizeHorizontalThumb(Cursors.SizeWE, HorizontalAlignment.Left));
            visCollec.Add(rightThumb = GetResizeHorizontalThumb(Cursors.SizeWE, HorizontalAlignment.Right));
            visCollec.Add(topThumb = GetResizeVerticalThumb(Cursors.SizeNS, VerticalAlignment.Top));
            visCollec.Add(bottomThumb = GetResizeVerticalThumb(Cursors.SizeNS, 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 - offset, AdornedElement.RenderSize.Height/2- offset), sz));

            leftThumb.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height / 2 - offset), sz));
            rightThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height/2 - offset), sz));
            topThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - offset, -offset), sz));
            bottomThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - offset, AdornedElement.RenderSize.Height - 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 GetResizeHorizontalThumb(Cursor cur, HorizontalAlignment hor)
        {           
            var thumb = new Thumb()
            {
                Background = Brushes.Red,
                Width = THUMB_SIZE,
                Height = THUMB_SIZE,
                HorizontalAlignment = hor,             
                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.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;
        }

        Thumb GetResizeVerticalThumb(Cursor cur, VerticalAlignment ver)
        {
            var thumb = new Thumb()
            {
                Background = Brushes.Red,
                Width = THUMB_SIZE,
                Height = THUMB_SIZE,
                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;
                }

                e.Handled = true;
            };
            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()
        {
            var converter = TypeDescriptor.GetConverter(typeof(Geometry));
            var geometry = new RectangleGeometry();                     
            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(Rectangle));
            fef.SetValue(Ellipse.FillProperty, back);
            fef.SetValue(Ellipse.StrokeProperty, Brushes.White);
            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;
            }
        }

    }


实力程序http://download.csdn.net/detail/new_smile/9537672

画图器编辑器C#WPF应用程序写的

  • 2011年05月12日 22:47
  • 24KB
  • 下载

wpf打造类似vs的编辑界面

  • 2011年06月19日 18:01
  • 87KB
  • 下载

WPF学习-文本编辑器(界面的<xaml>设计)

1.菜单栏:使用标签创建,创建一级和二级菜单项
  • yuhaoyang1
  • yuhaoyang1
  • 2012年04月24日 09:56
  • 2447

WPF 通过使用Frame 加载kindeditor文本编辑器

最近在做WPF 客户端发送信息的功能 想要实现发送的信息包含超链接 图片等等,由于以前WEB做过文本编辑器 所以打算通过Frame 加载html页面来实现文本的编辑 然后调用C#代码取得文本编辑器里面...
  • hyh834773759
  • hyh834773759
  • 2013年12月06日 14:56
  • 1549

用WPF做编辑器UI

最近在抽零碎的时间做特效编辑器的UI部分,和同事讨论了一下,采用WPF开发UI部分,其理由比较简单,该编辑器是为GameBryo服务的,而GB本身大多数编辑器的UI框架都采用C#开发,ToolBenc...
  • xiaohyy
  • xiaohyy
  • 2010年01月11日 21:05
  • 4190

WPF学习-文本编辑器(部分功能的设计)

1.文件-新建:检查文本中的内容是否为null,不为null,提示是否将当前内容保存,如果需要保存(MessageBoxResult.Yes),则保存。 表用系统自带的类SaveFileDialog...
  • yuhaoyang1
  • yuhaoyang1
  • 2012年04月24日 09:57
  • 5536

WPF中嵌入Office编辑器

http://www.cnblogs.com/youring2/p/3696437.html
  • stableboy
  • stableboy
  • 2017年02月05日 15:23
  • 1045

用WPF和D3D开发游戏编辑器简介(2)

距第一篇已经过去很长时间了,编辑器和引擎的开发并没有停止,每周都陆续有新的功能添加进去。在这几个月的时间里,wpf界面重新进行了自定义,风格更为简洁统一,编辑器代码也进行了重写,减少了不必要的更新操作...
  • miztook
  • miztook
  • 2012年03月31日 00:18
  • 1899

在C# winform程序中调用WPF写的数学公式编辑器

由于工作原因,需要在程序中加入数学公式编辑功能,因此在网上找了不少开源数学公式程序。经过比较,最终选择了Math-Editor-master程序(可以在github上搜索此名称)。我的程序(简称主程序...
  • gc_2299
  • gc_2299
  • 2017年11月12日 19:58
  • 42

移动端H5页面编辑器开发实战--原理结构篇

在去年10月份左右,接到了需求:开发一个H5移动端页面编辑器的任务,目的主要是解放公司内在制作这类网页的所投入的人力以及解决使用外部H5编辑器所涉及到的版权问题。 因此,一款能够与市面上已经成型的H5...
  • tech_meizu
  • tech_meizu
  • 2016年08月23日 10:55
  • 5485
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:wpf页面编辑器原理
举报原因:
原因补充:

(最多只允许输入30个字)