怎么在网上创建网站,南充网站建设多少钱,江苏网站建设功能,wamp wordpressWPF拖动改变大小系列
第一节 Grid内控件拖动调整大小 第二节 Canvas内控件拖动调整大小 第三节 窗口拖动调整大小 第四节 附加属性实现拖动调整大小 第五章 拓展更多调整大小功能#xff08;本章#xff09; 文章目录 WPF拖动改变大小系列前言一、添加的功能1、任意控件Drag…WPF拖动改变大小系列
第一节 Grid内控件拖动调整大小 第二节 Canvas内控件拖动调整大小 第三节 窗口拖动调整大小 第四节 附加属性实现拖动调整大小 第五章 拓展更多调整大小功能本章 文章目录 WPF拖动改变大小系列前言一、添加的功能1、任意控件DragResize2、边界限制3、交叉拖动1判断控件边界2固定到控件边界3事件转移 4、拖动点模板5、拖动点容器模板6、整体模板7、窗口平滑拖动8、拖动事件9、其他功能1适应MinWidth、MinHeight2适应MaxWidth、MaxHeight3适配任意dpi 二、完整代码三、使用示例0、基础功能1、引用命名空间2、使用附加属性 1、DragResize2、边界限制3、交叉拖动4、拖动点布局模板1自定义圆点24个顶点3单独定制每个点 5、拖动点容器模板1无Margin2设置Margin 6、整体模板7、窗口平滑拖动8、拖动事件9、其他功能1适应MinWidth、MinHeight2适应MaxWidth、MaxHeight 总结 前言
上一章我们已经实现了任意控件统一的拖动调整功能能够方便的给任意控件设置拖动调整大小。开发过程中发现还是有些功能可以继续拓展的比如cs代码触发拖动、自定义模板、交叉拖动、限制拖动范围等功能。有功能实现起来不算太容易却很有实用价值。 一、添加的功能
在第四章基础上添加了如下功能。
1、任意控件DragResize
我们知道wpf的Window有DragMove功能在鼠标左键按下事件中调用此方法就能实现拖动功能很方便。对于调整大小也可以实现类似的DragResize功能 实际效果和点击画板拖出一个形状差不多。
代码示例如下 /// summary/// 手动触发拖动改变大小与Window.DragMove类似,只能在鼠标左键按下时调用。/// 实际效果和点击画板拖出一个形状差不多。/// 此方法为拓展方法FrameworkElement的子类控件即有宽高属性的控件都可以调用此方法。/// /summary/// param nameelememt/param/// returns返回Taskawait等待拖动完成/returns/// exception crefInvalidOperationException/exceptionpublic static async Task DragResize(this FrameworkElement elememt){if (Mouse.LeftButton ! MouseButtonState.Pressed){throw new InvalidOperationException(Left button down to call this method);}if (elememt.Parent null elememt is not Window){throw new InvalidOperationException(Element should be on the visual tree);}//生成Resizeable对象第四章完整代码中。//获取右下角Thumb//手动触发Thumb拖动事件//等待拖动完成}2、边界限制
添加一个IsResizeInBounds附加属性表示拖动范围是否在父控件内。 代码示例如下
public static bool GetIsResizeInBounds(DependencyObject obj)
{return (bool)obj.GetValue(IsResizeInBoundsProperty);
}public static void SetIsResizeInBounds(DependencyObject obj, bool value)
{obj.SetValue(IsResizeInBoundsProperty, value);
}/// summary
/// 是否在父控件范围内拖动
/// /summary
public static readonly DependencyProperty IsResizeInBoundsProperty DependencyProperty.RegisterAttached(IsResizeInBounds, typeof(bool), typeof(Resize), new PropertyMetadata(false));第四章的拖动逻辑中添加相应的限制功能本质上就是判断如果超出边界则控件刚好依附在边界上代码如下: var dx left - margin.Left;var dy top - margin.Top;if (GetIsResizeInBounds(c)){var pos c.GetPosition();var parent _resizeTarget.Parent as FrameworkElement;Size size;if (parent null){size.Width SystemParameters.PrimaryScreenWidth;size.Height SystemParameters.PrimaryScreenHeight;}else{size.Width parent.ActualWidth;size.Height parent.ActualHeight;}if (pos.X dx 0){left -pos.X margin.Left;width pos.X c.ActualWidth;}else if (pos.X dx width size.Width){width size.Width - pos.X;right margin.Right c.ActualWidth - width;}if (pos.Y dy 0){top -pos.Y margin.Top;height pos.Y c.ActualHeight;}else if (pos.Y dy height size.Height){height size.Height - pos.Y;bottom margin.Bottom c.ActualHeight - height;}} 3、交叉拖动
交叉拖动是曾经用gdi画图时会出现的一种情况gdi绘制的宽高可以为负数所以可以直接穿过起点反向拖动也能绘制出图形。在wpf中的控件是不支持宽高负数的所以我们需要用其他方式实现。 下列步骤以横向为例
1判断控件边界 if (width 02固定到控件边界
SetTargetMargin为前3章的集合根据不同控件类型比如Window是设置Left、Top、Grid则设置Margin等。minWidth是控件的MinWidth属性。margin参考第四张完整代码。
if (thumb.HorizontalAlignment HorizontalAlignment.Left)
//左拖动点
{SetTargetMargin(new Thickness(margin.Left c.Width - minWidth, margin.Top, margin.Right - c.Width minWidth, margin.Bottom));
}
else
//右拖动点
{SetTargetMargin(new Thickness(margin.Left - c.Width minWidth, margin.Top, margin.Right c.Width - minWidth, margin.Bottom));
}3事件转移
//当前拖动点触发鼠标弹起事件
MouseButtonEventArgs upEvent new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
{ RoutedEvent UIElement.MouseLeftButtonUpEvent };
thumb.RaiseEvent(upEvent);
//反向拖动点触发鼠标按下事件
MouseButtonEventArgs downEvent new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
{ RoutedEvent UIElement.MouseLeftButtonDownEvent };
t.RaiseEvent(downEvent);4、拖动点模板
添加附加属性ThumbsTemplate
public static ControlTemplate GetThumbsTemplate(DependencyObject obj)
{return (ControlTemplate)obj.GetValue(ThumbsTemplateProperty);
}public static void SetThumbsTemplate(DependencyObject obj, ControlTemplate value)
{obj.SetValue(ThumbsTemplateProperty, value);
}/// summary
/// 拖动点的模板
/// /summary
public static readonly DependencyProperty ThumbsTemplateProperty DependencyProperty.RegisterAttached(ThumbsTemplate, typeof(ControlTemplate), typeof(Resize), new PropertyMetadata(null));生成拖动点时会应用模板
var thumbsTemplate GetThumbsTemplate(_resizeTarget);
thumb.Template thumbsTemplate;5、拖动点容器模板
拖动点的容器模板主要用于设置margin调整拖动点的整体位置添加附加属性ThumbsPanel。 public static ItemsPanelTemplate GetThumbsPanel(DependencyObject obj){return (ItemsPanelTemplate)obj.GetValue(ThumbsPanelProperty);}public static void SetThumbsPanel(DependencyObject obj, ItemsPanelTemplate value){obj.SetValue(ThumbsPanelProperty, value);}/// summary/// 拖动点的容器主要用于设置margin/// /summarypublic static readonly DependencyProperty ThumbsPanelProperty DependencyProperty.RegisterAttached(ThumbsPanel, typeof(ItemsPanelTemplate), typeof(Resize), new PropertyMetadata(null));生成拖动点布局时会应用模板
var itemsPanel GetThumbsPanel(_resizeTarget);
_defalutPanel.ItemsPanel itemsPanel;6、整体模板
拖动点模板和拖动点布局模板已经很大程度灵活了使用如果需要更高的定制性直接使用整体模板整体模板赋值后拖动点模板和拖动点布局模板会失效。此功能与第四章的ResizeTemplate相同但名称改为Template。基本规则是第一级控件为容器、第二级控件为Thumb类型自动识别为拖动点拖动方向由HorizontalAlignment和VerticalAlignment决定。
7、窗口平滑拖动
之所有要对窗口拖动平滑处理是因为自定义的调整大小只能设置Window的Left、Top、Width、Height当窗口进行左或上拖动时右或下会出现残影这种情况通过SetWindowPos和MoveWindow也无法改善。在不使用窗口自带的拖动功能的情况下目前笔者研究出的方法就是使用透明窗口全屏控件模拟窗口进行拖动。当然这种实现的限制就是一定要透明窗口AllowTransparency为true或者WindowChrome的GlassFrameThickness为-1。
因为这种实现还不是很完美对装饰器不兼容所以提供IsWindowDragSmooth属性可以打开和关闭功能。
public static bool GetIsWindowDragSmooth(DependencyObject obj)
{return (bool)obj.GetValue(IsWindowDragSmoothProperty);
}public static void SetIsWindowDragSmooth(DependencyObject obj, bool value)
{obj.SetValue(IsWindowDragSmoothProperty, value);
}/// summary
/// 拖拽窗口调整大小是否平滑处理作用是避免拖拽窗口左上时右下闪烁。
/// 此属性只对窗口有效
/// 此属性为true时需要透明窗口才能生效即AllowTransparency为true或者WindowChrome的GlassFrameThickness为-1。
/// 当前版本不兼容有装饰器的窗口拖动中装饰器可能会显示在窗口外面。
/// /summary
// Using a DependencyProperty as the backing store for IsWindowDragSmooth. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsWindowDragSmoothProperty DependencyProperty.RegisterAttached(IsWindowDragSmooth, typeof(bool), typeof(Resize), new PropertyMetadata(false));8、拖动事件
提供3个拖动事件拖动开始、拖动变化、拖动结束。 代码示例如下
/// summary
/// 拖动开始事件
/// /summary
public static readonly RoutedEvent DragResizeStartedEvent EventManager.RegisterRoutedEvent(DragResizeStarted, RoutingStrategy.Direct, typeof(EventHandlerDragResizeStartedEventArgs), typeof(Resize));
/// summary
/// 拖动变化事件
/// /summary
public static readonly RoutedEvent DragResizeDeltaEvent EventManager.RegisterRoutedEvent(DragResizeDelta, RoutingStrategy.Direct, typeof(EventHandlerDragResizeDeltaEventArgs), typeof(Resize));
/// summary
/// 拖动结束事件
/// /summary
public static readonly RoutedEvent DragResizeCompletedEvent EventManager.RegisterRoutedEvent(DragResizeCompleted, RoutingStrategy.Direct, typeof(EventHandlerDragResizeCompletedEventArgs), typeof(Resize));9、其他功能
1适应MinWidth、MinHeight
在第四章完整带的基础上将边界判断修改为控件的MinWidth、MinHeight即可。 横向
if (width minWidth/*原本是0*/)
{//略
}纵向与横向逻辑一致修改对应变量即可略
2适应MaxWidth、MaxHeight
超过了最大值需要进行修正示例如下 横向
if (width c.MaxWidth)
{if (thumb.HorizontalAlignment HorizontalAlignment.Left){left width - c.MaxWidth;right margin.Right;}else{left margin.Left;right width - c.MaxWidth;}width c.MaxWidth;
}纵向与横向逻辑一致修改对应变量即可略。
3适配任意dpi
所有改变坐标以及大小的代码已经适配了任意dpi。 主要注意的就是PointToScreen得到的坐标需要dpi转换。 下列是获取dpi的方法。
static Point GetDpiFromVisual(Visual visual)
{var source PresentationSource.FromVisual(visual);var dpiX 96.0;var dpiY 96.0;if (source?.CompositionTarget ! null){dpiX 96.0 * source.CompositionTarget.TransformToDevice.M11;dpiY 96.0 * source.CompositionTarget.TransformToDevice.M22;}return new Point(dpiX, dpiY);
}二、完整代码
vs2022 wpf .net 6.0 项目包含了第四章的功能不需要重复下载。 之后上传 三、使用示例
0、基础功能
这个是与第四章一致的基础功能。
1、引用命名空间
Window 的其他属性略
Window xmlns:acclr-namespace:AC/2、使用附加属性
需要某个控件可以拖动调整大小则
Grid ac:Resize.IsResizeableTrue /1、DragResize
DragResize需要在鼠标左键按下事件中使用对已存在的控件或者动态生成控件使用。此方法不需要ac:Resize.IsResizeableTrue也可以使用。 xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizemc:IgnorabledTitleMainWindow Height450 Width800WindowStyleNoneResizeModeNoResizeGrid x:Namegrid BackgroundSeaGreen MouseLeftButtonDownWindow_MouseLeftButtonDown/
/Window因为是拓展方法所以获取到控件对象直接调用DragResize即可。 cs
using AC;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;namespace WpfResize
{/// summary/// Interaction logic for MainWindow.xaml/// /summarypublic partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private async void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){//生成控件var border new Border();border.Background Brushes.Azure;border.Width 0;border.Height 0;//加入到容器grid.Children.Add(border);//拖出控件await border.DragResize();//如果宽高为0则移除if (border.Width 0|| border.Height 0){grid.Children.Remove(border);}}}
}效果预览 注qq录制鼠标出现了偏移
2、边界限制
设置ac:Resize.IsResizeInBoundsTrue即可。边界限制的范围是父控件。 xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800WindowStyleNoneResizeModeNoResize Grid x:Namegrid BackgroundSeaGreenBorder BorderThickness1 BorderBrushWhite Margin40StackPanelBorder ac:Resize.IsResizeableTrue ac:Resize.IsResizeInBoundsFalse BackgroundWhite Height100 Width200 CornerRadius10 TextBlock HorizontalAlignmentCenter VerticalAlignmentCenter Text不限制边界/TextBlock/BorderBorder ac:Resize.IsResizeableTrue ac:Resize.IsResizeInBoundsTrue Margin0,20,0,0 BackgroundWhite Height100 Width200 CornerRadius10 TextBlock HorizontalAlignmentCenter VerticalAlignmentCenter Text限制边界/TextBlock/Border/StackPanel/Border/Grid
/Window效果预览 注qq录制鼠标出现了偏移
3、交叉拖动
通过附加属性ac:Resize.IsAllowsCrossover设置是否交叉拖动默认为true。 xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800WindowStyleNoneResizeModeNoResize Grid x:Namegrid BackgroundSeaGreenStackPanelBorder Margin0,20,0,0 ac:Resize.IsResizeableTrue ac:Resize.IsAllowsCrossoverFalse BackgroundWhite Height100 Width200 CornerRadius10 TextBlock HorizontalAlignmentCenter VerticalAlignmentCenter Text不允许交叉拖动/TextBlock/BorderBorder ac:Resize.IsResizeableTrue ac:Resize.IsAllowsCrossoverTrue Margin0,20,0,0 BackgroundWhite Height100 Width200 CornerRadius10 TextBlock HorizontalAlignmentCenter VerticalAlignmentCenter Text允许交叉拖动/TextBlock/Border/StackPanel/Grid
/Window效果预览 注qq录制鼠标出现了偏移
4、拖动点布局模板
通过ac:Resize.ThumbsTemplate设置拖动点模板
1自定义圆点
xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 Grid x:Namegrid BackgroundWhiteGrid Margin0,20,0,0 ac:Resize.IsResizeableTrue ac:Resize.IsAllowsCrossoverFalse BackgroundSeaGreen Height100 Width200 ac:Resize.ThumbsTemplateControlTemplate Border BorderBrushGray BorderThickness2 CornerRadius8 BackgroundWhite Width16 Height16//ControlTemplate/ac:Resize.ThumbsTemplateTextBlock HorizontalAlignmentCenter VerticalAlignmentCenter ForegroundWhite Text自定义拖动点模板/TextBlock/Grid/Grid
/Window效果预览
24个顶点
xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 WindowStyleNoneResizeModeNoResizeGrid x:Namegrid BackgroundWhiteGrid Margin0,20,0,0 ac:Resize.IsResizeableTrue ac:Resize.IsAllowsCrossoverFalse BackgroundSeaGreen Height100 Width200 ac:Resize.ThumbsTemplateControlTemplate Border x:Namebrd BorderBrushGray BorderThickness2 CornerRadius8 BackgroundWhite Width16 Height16/!--通过触发器隐藏4条边上的点--ControlTemplate.Triggers!--左右两条边上的点--Trigger PropertyHorizontalAlignment ValueStretchSetter TargetNamebrd PropertyVisibility ValueCollapsed /Setter/Trigger!--上下两条边上的点--Trigger PropertyVerticalAlignment ValueStretchSetter TargetNamebrd PropertyVisibility ValueCollapsed /Setter/Trigger/ControlTemplate.Triggers/ControlTemplate/ac:Resize.ThumbsTemplateTextBlock HorizontalAlignmentCenter VerticalAlignmentCenter ForegroundWhite Text自定义拖动点模板/TextBlock/Grid/Grid
/Window效果预览
3单独定制每个点
通过MultiTrigger触发器来区分每个点。 xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 WindowStyleNoneResizeModeNoResizeGrid x:Namegrid BackgroundWhiteGrid Margin0,20,0,0 ac:Resize.IsResizeableTrue ac:Resize.IsAllowsCrossoverFalse BackgroundSeaGreen Height100 Width200 ac:Resize.ThumbsTemplateControlTemplate Border x:Namebrd BorderBrushGray BorderThickness2 CornerRadius8 BackgroundWhite Width16 Height16/ControlTemplate.Triggers!--左上--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueLeft /ConditionCondition PropertyVerticalAlignment ValueTop /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueAqua/Setter/MultiTrigger!--右上--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueRight /ConditionCondition PropertyVerticalAlignment ValueTop /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueDarkGoldenrod/Setter/MultiTrigger!--右下--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueRight /ConditionCondition PropertyVerticalAlignment ValueBottom /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueDeepPink/Setter/MultiTrigger!--左下--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueLeft /ConditionCondition PropertyVerticalAlignment ValueBottom /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueRed/Setter/MultiTrigger!--上--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueStretch /ConditionCondition PropertyVerticalAlignment ValueTop /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueGold/Setter/MultiTrigger!--下--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueStretch /ConditionCondition PropertyVerticalAlignment ValueBottom /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueIndigo/Setter/MultiTrigger!--左--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueLeft /ConditionCondition PropertyVerticalAlignment ValueStretch /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueBlue/Setter/MultiTrigger!--右--MultiTriggerMultiTrigger.ConditionsCondition PropertyHorizontalAlignment ValueRight /ConditionCondition PropertyVerticalAlignment ValueStretch /Condition/MultiTrigger.ConditionsSetter TargetNamebrd PropertyBorderBrush ValueGreen/Setter/MultiTrigger/ControlTemplate.Triggers/ControlTemplate/ac:Resize.ThumbsTemplateTextBlock HorizontalAlignmentCenter VerticalAlignmentCenter ForegroundWhite Text自定义拖动点模板/TextBlock/Grid/Grid
/Window效果预览 5、拖动点容器模板
通过ac:Resize.ThumbsPanel设置拖动点容器模板主要作用是设置margin方便调整拖动点的偏移。 默认的容器有Margin-5的偏移。
1无Margin
此示例是为了说明无Margin的情况。 xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 WindowStyleNoneResizeModeNoResizeGrid x:Namegrid BackgroundWhiteGrid Margin0,20,0,0 ac:Resize.IsResizeableTrue ac:Resize.IsAllowsCrossoverFalse BackgroundSeaGreen Height100 Width200 ac:Resize.ThumbsTemplateControlTemplate Border x:Namebrd BorderBrushGray BorderThickness2 CornerRadius8 BackgroundWhite Width16 Height16//ControlTemplate/ac:Resize.ThumbsTemplateac:Resize.ThumbsPanelItemsPanelTemplateGrid/Grid/ItemsPanelTemplate/ac:Resize.ThumbsPanelTextBlock HorizontalAlignmentCenter VerticalAlignmentCenter ForegroundWhite Text自定义拖点容器模板/TextBlock/Grid/Grid
/Window效果预览
2设置Margin
Margin设置为拖动点的一半大小就刚好在边线中间。 xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 WindowStyleNoneResizeModeNoResizeGrid x:Namegrid BackgroundWhiteGrid Margin0,20,0,0 ac:Resize.IsResizeableTrue ac:Resize.IsAllowsCrossoverFalse BackgroundSeaGreen Height100 Width200 ac:Resize.ThumbsTemplateControlTemplate Border x:Namebrd BorderBrushGray BorderThickness2 CornerRadius8 BackgroundWhite Width16 Height16//ControlTemplate/ac:Resize.ThumbsTemplateac:Resize.ThumbsPanelItemsPanelTemplateGrid Margin-8/Grid/ItemsPanelTemplate/ac:Resize.ThumbsPanelTextBlock HorizontalAlignmentCenter VerticalAlignmentCenter ForegroundWhite Text自定义拖点容器模板/TextBlock/Grid/Grid
/Window效果预览
6、整体模板
设置整体模板Template后会覆盖拖动点模板和拖动点布局模板。规则是第一级控件为容器、第二级控件为Thumb类型自动识别为拖动点拖动方向由HorizontalAlignment和VerticalAlignment决定 即可以有任意个拖动点Thumb也可以放任意其他控件。
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 WindowStyleNoneResizeModeNoResizeGrid x:Namegrid BackgroundWhiteGrid Margin0,20,0,0 ac:Resize.IsResizeableTrue BackgroundSeaGreen Height100 Width200 ac:Resize.TemplateControlTemplate Grid Margin-4Grid.ResourcesStyle TargetTypeThumbSetter PropertyWidth Value8/SetterSetter PropertyHeight Value8/SetterSetter PropertyTemplateSetter.ValueControlTemplateBorder BackgroundAqua/Border/ControlTemplate/Setter.Value/Setter/Style/Grid.ResourcesBorder BorderBrushAqua BorderThickness2 Margin4/Border!--左--Thumb HorizontalAlignmentLeft CursorSizeWE/!--上--Thumb VerticalAlignmentTop CursorSizeNS/!--右--Thumb HorizontalAlignmentRight CursorSizeWE/!--下--Thumb VerticalAlignmentBottom CursorSizeNS/!--左上--Thumb HorizontalAlignmentLeft VerticalAlignmentTop CursorSizeNWSE/!--右上--Thumb HorizontalAlignmentRight VerticalAlignmentTop CursorSizeNESW/!--右下--Thumb HorizontalAlignmentRight VerticalAlignmentBottom CursorSizeNWSE/!--左下--Thumb HorizontalAlignmentLeft VerticalAlignmentBottom CursorSizeNESW//Grid/ControlTemplate/ac:Resize.TemplateTextBlock HorizontalAlignmentCenter VerticalAlignmentCenter ForegroundWhite Text自定义整体模板/TextBlock/Grid/Grid
/Window效果预览
7、窗口平滑拖动
窗口为透明窗口AllowTransparency为true或者WindowChrome的GlassFrameThickness为-1附加属性 ac:Resize.IsWindowDragSmooth设置为true即可以实现平滑拖动。 注当前版本和装饰器不兼容拖动时装饰器可能显示在窗口外面谨慎使用此属性
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 WindowStyleNoneResizeModeNoResizeAllowsTransparencyTrueac:Resize.IsResizeableTrueac:Resize.IsWindowDragSmoothTrueGrid BackgroundSeaGreen /
/Window作为对比先展示非平滑拖动 注qq录制鼠标出现了偏移
设置平滑拖动效果预览 注qq录制鼠标出现了偏移
8、拖动事件
3个事件拖动开始ac:Resize.DragResizeStarted、拖动变化ac:Resize.DragResizeDelta、拖动结束ac:Resize.DragResizeCompleted xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 Grid BackgroundSeaGreen Border BackgroundAqua Width200 Height200 ac:Resize.IsResizeableTrue ac:Resize.DragResizeStartedBorder_DragResizeStarted ac:Resize.DragResizeCompletedBorder_DragResizeCompleted ac:Resize.DragResizeDeltaBorder_DragResizeDelta/Border/Grid
/Windowcs
using AC;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;namespace WpfResize
{/// summary/// Interaction logic for MainWindow.xaml/// /summarypublic partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void Border_DragResizeStarted(object sender, DragResizeStartedEventArgs e){Console.WriteLine(开始拖动);}private void Border_DragResizeCompleted(object sender, DragResizeCompletedEventArgs e){Console.WriteLine(结束拖动);}private void Border_DragResizeDelta(object sender, DragResizeDeltaEventArgs e){Console.WriteLine(横向变化:e.HorizontalChange 纵向变化:e.VerticalChange 宽变化: e.WidthChange 高变化: e.HeightChange);}}
}
效果预览 注qq录制鼠标出现了偏移
9、其他功能
1适应MinWidth、MinHeight
xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 Grid BackgroundSeaGreen Border BackgroundAqua MinWidth100 MinHeight100 Width200 Height200 ac:Resize.IsResizeableTrue /Border/Grid
/Window效果预览 注qq录制鼠标出现了偏移
2适应MaxWidth、MaxHeight
xaml
Window x:ClassWpfResize.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfResizexmlns:acclr-namespace:ACmc:IgnorabledTitleMainWindow Height450 Width800 Grid BackgroundSeaGreen Border BackgroundAqua MaxWidth200 MaxHeight200 Width100 Height100 ac:Resize.IsResizeableTrue /Border/Grid
/Window效果预览 总结
以上就是今天要讲的内容拓展后的功能更加全面以及兼容性更强了比如DragRezie就可以用于画板边界限制也是比较实用的功能拖动点模板简化了自定义的难度拖动事件可以用于实现撤销重做功能窗口平滑拖动优化了使用体验。但是还是有些功能不够完需要后期继续优化。总的来说本文实现的拖动调整大小模块已经变得更加方便实用后期还会继续完善优化。