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

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import