C# wpf Canvas中如何实现控件拖动调整大小(canvas,wpf,开发技术)

时间:2024-05-03 11:32:06 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

这篇“C#wpfCanvas中如何实现控件拖动调整大小”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#wpfCanvas中如何实现控件拖动调整大小”文章吧。

    前言

    我们做图片编辑工具、视频编辑工具、或者画板有时需要实现控件缩放功能,比如图片或图形可以拉伸放大或缩小,实现这种功能通常需要8个点,对应4条边和4个角,在wpf中通常可以使用装饰器实现。

    一、功能说明

    8个点方放置在控件的8个方位上,通过拖动这些点对控件进行拉伸或缩小,示意图如下:

    C# wpf Canvas中如何实现控件拖动调整大小

    二、如何实现?

    1.继承Adorner

    通过装饰器的方式添加8个点在控件上,这样既可以不影响控件布局,又可以自由摆放8点控件。通过重写方法,给装饰添加控件。必要的重写的方法如下面示例所示:

    publicclassCanvasAdorner:Adorner{//获取装饰器的元素个数protectedoverrideVisualGetVisualChild(intindex);//指定装饰器子元素个数protectedoverrideintVisualChildrenCount{get;}//布局,添加的子元素需要手动布局。protectedoverrideSizeArrangeOverride(SizefinalSize);}

    2.使用Thumb

    因为Thumb实现拖动比较容易,有相关事件获取拖动距离。在装饰器中定义8个Thumb,对应8个方位点。
    示例代码如下:

    //4条边Thumb_leftThumb,_topThumb,_rightThumb,_bottomThumb;//4个角Thumb_lefTopThumb,_rightTopThumb,_rightBottomThumb,_leftbottomThumb;

    初始化

    publicCanvasAdorner(UIElementadornedElement):base(adornedElement){//初始化thumb_leftThumb=newThumb();_leftThumb.HorizontalAlignment=HorizontalAlignment.Left;_leftThumb.VerticalAlignment=VerticalAlignment.Center;_leftThumb.Cursor=Cursors.SizeWE;//其他略...}

    3.实现拖动逻辑

    在Thumb的DragDelta事件可以获取拖动距离,根据八个方位的不同计算并修改控件的大小。

    privatevoidThumb_DragDelta(objectsender,DragDeltaEventArgse){//1.右侧点HorizontalChange加宽//2.左侧点HorizontalChange减宽,加左移//3.下侧点VerticalChange加高//4.上侧点VerticalChange减高,加上移}

    三、完整代码

    代码如下:

    publicclassCanvasAdorner:Adorner{//4条边Thumb_leftThumb,_topThumb,_rightThumb,_bottomThumb;//4个角Thumb_lefTopThumb,_rightTopThumb,_rightBottomThumb,_leftbottomThumb;//布局容器,如果不使用布局容器,则需要给上述8个控件布局,实现和Grid布局定位是一样的,会比较繁琐且意义不大。Grid_grid;UIElement_adornedElement;publicCanvasAdorner(UIElementadornedElement):base(adornedElement){_adornedElement=adornedElement;//初始化thumb_leftThumb=newThumb();_leftThumb.HorizontalAlignment=HorizontalAlignment.Left;_leftThumb.VerticalAlignment=VerticalAlignment.Center;_leftThumb.Cursor=Cursors.SizeWE;_topThumb=newThumb();_topThumb.HorizontalAlignment=HorizontalAlignment.Center;_topThumb.VerticalAlignment=VerticalAlignment.Top;_topThumb.Cursor=Cursors.SizeNS;_rightThumb=newThumb();_rightThumb.HorizontalAlignment=HorizontalAlignment.Right;_rightThumb.VerticalAlignment=VerticalAlignment.Center;_rightThumb.Cursor=Cursors.SizeWE;_bottomThumb=newThumb();_bottomThumb.HorizontalAlignment=HorizontalAlignment.Center;_bottomThumb.VerticalAlignment=VerticalAlignment.Bottom;_bottomThumb.Cursor=Cursors.SizeNS;_lefTopThumb=newThumb();_lefTopThumb.HorizontalAlignment=HorizontalAlignment.Left;_lefTopThumb.VerticalAlignment=VerticalAlignment.Top;_lefTopThumb.Cursor=Cursors.SizeNWSE;_rightTopThumb=newThumb();_rightTopThumb.HorizontalAlignment=HorizontalAlignment.Right;_rightTopThumb.VerticalAlignment=VerticalAlignment.Top;_rightTopThumb.Cursor=Cursors.SizeNESW;_rightBottomThumb=newThumb();_rightBottomThumb.HorizontalAlignment=HorizontalAlignment.Right;_rightBottomThumb.VerticalAlignment=VerticalAlignment.Bottom;_rightBottomThumb.Cursor=Cursors.SizeNWSE;_leftbottomThumb=newThumb();_leftbottomThumb.HorizontalAlignment=HorizontalAlignment.Left;_leftbottomThumb.VerticalAlignment=VerticalAlignment.Bottom;_leftbottomThumb.Cursor=Cursors.SizeNESW;_grid=newGrid();_grid.Children.Add(_leftThumb);_grid.Children.Add(_topThumb);_grid.Children.Add(_rightThumb);_grid.Children.Add(_bottomThumb);_grid.Children.Add(_lefTopThumb);_grid.Children.Add(_rightTopThumb);_grid.Children.Add(_rightBottomThumb);_grid.Children.Add(_leftbottomThumb);AddVisualChild(_grid);foreach(Thumbthumbin_grid.Children){thumb.Width=16;thumb.Height=16;thumb.Background=Brushes.Green;thumb.Template=newControlTemplate(typeof(Thumb)){VisualTree=GetFactory(newSolidColorBrush(Colors.White))};thumb.DragDelta+=Thumb_DragDelta;}}protectedoverrideVisualGetVisualChild(intindex){return_grid;}protectedoverrideintVisualChildrenCount{get{return1;}}protectedoverrideSizeArrangeOverride(SizefinalSize){//直接给grid布局,grid内部的thumb会自动布局。_grid.Arrange(newRect(newPoint(-_leftThumb.Width/2,-_leftThumb.Height/2),newSize(finalSize.Width+_leftThumb.Width,finalSize.Height+_leftThumb.Height)));returnfinalSize;}//拖动逻辑privatevoidThumb_DragDelta(objectsender,DragDeltaEventArgse){varc=_adornedElementasFrameworkElement;varthumb=senderasFrameworkElement;doubleleft,top,width,height;if(thumb.HorizontalAlignment==HorizontalAlignment.Left){left=double.IsNaN(Canvas.GetLeft(c))?0:Canvas.GetLeft(c)+e.HorizontalChange;width=c.Width-e.HorizontalChange;}else{left=Canvas.GetLeft(c);width=c.Width+e.HorizontalChange;}if(thumb.VerticalAlignment==VerticalAlignment.Top){top=double.IsNaN(Canvas.GetTop(c))?0:Canvas.GetTop(c)+e.VerticalChange;height=c.Height-e.VerticalChange;}else{top=Canvas.GetTop(c);height=c.Height+e.VerticalChange;}if(thumb.HorizontalAlignment!=HorizontalAlignment.Center){if(width>=0){Canvas.SetLeft(c,left);c.Width=width;}}if(thumb.VerticalAlignment!=VerticalAlignment.Center){if(height>=0){Canvas.SetTop(c,top);c.Height=height;}}}//thumb的样式FrameworkElementFactoryGetFactory(Brushback){varfef=newFrameworkElementFactory(typeof(Ellipse));fef.SetValue(Ellipse.FillProperty,back);fef.SetValue(Ellipse.StrokeProperty,newSolidColorBrush((Color)ColorConverter.ConvertFromString("#999999")));fef.SetValue(Ellipse.StrokeThicknessProperty,(double)2);returnfef;}}

    四、使用示例

    示例代码如下:
    xaml

    <CanvasMargin="20"><Borderx:Name="border"Width="200"Height="200"Background="Gray"></Border></Canvas>

    在窗口或控件的Loaded事件中添加装饰器:
    cs

    privatevoidwindow_Loaded(objectsender,RoutedEventArgse){varlayer=AdornerLayer.GetAdornerLayer(border);layer.Add(newCanvasAdorner(border));}

    效果预览:

    C# wpf Canvas中如何实现控件拖动调整大小

    以上就是关于“C#wpfCanvas中如何实现控件拖动调整大小”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

    本文:C# wpf Canvas中如何实现控件拖动调整大小的详细内容,希望对您有所帮助,信息来源于网络。
    上一篇:MySQL架构设计实例分析下一篇:

    6 人围观 / 0 条评论 ↓快速评论↓

    (必须)

    (必须,保密)

    阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18