C# wpf Grid中实现控件拖动调整大小

2024-08-29 05:48

本文主要是介绍C# wpf Grid中实现控件拖动调整大小,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

WPF拖动改变大小系列

第一节 Grid内控件拖动调整大小(本章)
第二节 Canvas内控件拖动调整大小
第三节 窗口拖动调整大小
第四节 附加属性实现拖动调整大小
第五章 拓展更多调整大小功能


文章目录

  • WPF拖动改变大小系列
  • 前言
  • 一、功能说明
  • 二、如何实现?
    • 1.继承Adorner
    • 2.使用Thumb
    • 3.实现拖动逻辑
  • 三、完整代码
  • 四、使用示例
  • 总结


前言

在《C# wpf Canvas中实现控件动态调整大小》中我们实现了Canvas中的控件动态调整大小,由于Grid也是可层叠布局,在Grid中也是可以实现动态调整大小的。


一、功能说明

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


二、如何实现?

1.继承Adorner

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

public class GridAdorner : Adorner
{//获取装饰器的元素个数protected override Visual GetVisualChild(int index);//指定装饰器子元素个数protected override int VisualChildrenCount{get;}//布局,添加的子元素需要手动布局。protected override Size ArrangeOverride(Size finalSize);      
}

2.使用Thumb

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

//4条边
Thumb _leftThumb, _topThumb, _rightThumb, _bottomThumb;
//4个角
Thumb _lefTopThumb, _rightTopThumb, _rightBottomThumb, _leftbottomThumb;

初始化

 public GridAdorner(UIElement adornedElement) : base(adornedElement){//初始化thumb_leftThumb = new Thumb();_leftThumb.HorizontalAlignment = HorizontalAlignment.Left;_leftThumb.VerticalAlignment = VerticalAlignment.Center;_leftThumb.Cursor = Cursors.SizeWE;//其他略...
}

3.实现拖动逻辑

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

private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
//1.右侧点HorizontalChange加宽,右边距减HorizontalChange
//2.左侧点HorizontalChange减宽,左边距加HorizontalChange
//3.下侧点VerticalChange加高,下边距减VerticalChange
//4.上侧点VerticalChange减高,上边距加VerticalChange
}

三、完整代码

代码如下:

 public class GridAdorner : Adorner{//4条边Thumb _leftThumb, _topThumb, _rightThumb, _bottomThumb;//4个角Thumb _lefTopThumb, _rightTopThumb, _rightBottomThumb, _leftbottomThumb;//布局容器,如果不使用布局容器,则需要给上述8个控件布局,实现和Grid布局定位是一样的,会比较繁琐且意义不大。Grid _grid;UIElement _adornedElement;public GridAdorner(UIElement adornedElement) : base(adornedElement){_adornedElement = adornedElement;//初始化thumb_leftThumb = new Thumb();_leftThumb.HorizontalAlignment = HorizontalAlignment.Left;_leftThumb.VerticalAlignment = VerticalAlignment.Center;_leftThumb.Cursor = Cursors.SizeWE;_topThumb = new Thumb();_topThumb.HorizontalAlignment = HorizontalAlignment.Center;_topThumb.VerticalAlignment = VerticalAlignment.Top;_topThumb.Cursor = Cursors.SizeNS;_rightThumb = new Thumb();_rightThumb.HorizontalAlignment = HorizontalAlignment.Right;_rightThumb.VerticalAlignment = VerticalAlignment.Center;_rightThumb.Cursor = Cursors.SizeWE;_bottomThumb = new Thumb();_bottomThumb.HorizontalAlignment = HorizontalAlignment.Center;_bottomThumb.VerticalAlignment = VerticalAlignment.Bottom;_bottomThumb.Cursor = Cursors.SizeNS;_lefTopThumb = new Thumb();_lefTopThumb.HorizontalAlignment = HorizontalAlignment.Left;_lefTopThumb.VerticalAlignment = VerticalAlignment.Top;_lefTopThumb.Cursor = Cursors.SizeNWSE;_rightTopThumb = new Thumb();_rightTopThumb.HorizontalAlignment = HorizontalAlignment.Right;_rightTopThumb.VerticalAlignment = VerticalAlignment.Top;_rightTopThumb.Cursor = Cursors.SizeNESW;_rightBottomThumb = new Thumb();_rightBottomThumb.HorizontalAlignment = HorizontalAlignment.Right;_rightBottomThumb.VerticalAlignment = VerticalAlignment.Bottom;_rightBottomThumb.Cursor = Cursors.SizeNWSE;_leftbottomThumb = new Thumb();_leftbottomThumb.HorizontalAlignment = HorizontalAlignment.Left;_leftbottomThumb.VerticalAlignment = VerticalAlignment.Bottom;_leftbottomThumb.Cursor = Cursors.SizeNESW;_grid = new Grid();_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 (Thumb thumb in _grid.Children){thumb.Width = 16;thumb.Height = 16;thumb.Background = Brushes.Green;thumb.Template = new ControlTemplate(typeof(Thumb)){VisualTree = GetFactory(new SolidColorBrush(Colors.White))};thumb.DragDelta += Thumb_DragDelta;}}protected override Visual GetVisualChild(int index){return _grid;}protected override int VisualChildrenCount{get{return 1;}}protected override Size ArrangeOverride(Size finalSize){//直接给grid布局,grid内部的thumb会自动布局。_grid.Arrange(new Rect(new Point(-_leftThumb.Width / 2, -_leftThumb.Height / 2), new Size(finalSize.Width + _leftThumb.Width, finalSize.Height + _leftThumb.Height)));return finalSize;}//拖动逻辑private void Thumb_DragDelta(object sender, DragDeltaEventArgs e){var c = _adornedElement as FrameworkElement;var thumb = sender as FrameworkElement;double left, top, right, bottom, width, height;if (thumb.HorizontalAlignment == HorizontalAlignment.Left){right = c.Margin.Right;left = c.Margin.Left + e.HorizontalChange;width =(double.IsNaN(c.Width)?c.ActualWidth:c.Width)- e.HorizontalChange;}else{left = c.Margin.Left;right = c.Margin.Right - e.HorizontalChange;width = (double.IsNaN(c.Width) ? c.ActualWidth : c.Width )+ e.HorizontalChange;}if (thumb.VerticalAlignment == VerticalAlignment.Top){bottom = c.Margin.Bottom;top = c.Margin.Top + e.VerticalChange;height = (double.IsNaN(c.Height) ? c.ActualHeight : c.Height) - e.VerticalChange;}else{top = c.Margin.Top;bottom = c.Margin.Bottom - e.VerticalChange;height = (double.IsNaN(c.Height) ? c.ActualHeight : c.Height )+ e.VerticalChange;}if (thumb.HorizontalAlignment != HorizontalAlignment.Center){if (width >= 0){c.Margin = new Thickness(left, c.Margin.Top, right, c.Margin.Bottom);c.Width = width;}}if (thumb.VerticalAlignment != VerticalAlignment.Center){if (height >= 0){c.Margin = new Thickness(c.Margin.Left, top, c.Margin.Right, bottom);c.Height = height;}}}//thumb的样式FrameworkElementFactory GetFactory(Brush back){var fef = new FrameworkElementFactory(typeof(Ellipse));fef.SetValue(Ellipse.FillProperty, back);fef.SetValue(Ellipse.StrokeProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString("#999999")));fef.SetValue(Ellipse.StrokeThicknessProperty, (double)2);return fef;}}

四、使用示例

示例代码如下:
xaml

<Grid><Border  x:Name="border"  Width="200" Height="200"  Background="Gray" ></Border>
</Grid>

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

private void window_Loaded(object sender, RoutedEventArgs e)
{var layer = AdornerLayer.GetAdornerLayer(border);layer.Add(new GridAdorner(border));
}

效果预览:
在这里插入图片描述


总结

以上就是今天要讲的内容,本文讲述了Grid中控件缩放的方法与实现,与Canvas的实现大部分是相同的,唯一的区别就是设置Margin,总得来说还是比较容易实现的,最终呈现的效果也是比较不错的。

这篇关于C# wpf Grid中实现控件拖动调整大小的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1117015

相关文章

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式