C# wpf Grid中實(shí)現(xiàn)控件拖動(dòng)調(diào)整大小的示例代碼
前言
在《C# wpf Canvas中實(shí)現(xiàn)控件動(dòng)態(tài)調(diào)整大小》中我們實(shí)現(xiàn)了Canvas中的控件動(dòng)態(tài)調(diào)整大小,由于Grid也是可層疊布局,在Grid中也是可以實(shí)現(xiàn)動(dòng)態(tài)調(diào)整大小的。
一、功能說(shuō)明
8個(gè)點(diǎn)方放置在控件的8個(gè)方位上,通過(guò)拖動(dòng)這些點(diǎn)對(duì)控件進(jìn)行拉伸或縮小,示意圖如下:
二、如何實(shí)現(xiàn)?
1.繼承Adorner
通過(guò)裝飾器的方式添加8個(gè)點(diǎn)在控件上,這樣既可以不影響控件布局,又可以自由擺放8點(diǎn)控件。通過(guò)重寫(xiě)方法,給裝飾添加控件。必要的重寫(xiě)的方法如下面示例所示:
public class GridAdorner : Adorner { //獲取裝飾器的元素個(gè)數(shù) protected override Visual GetVisualChild(int index); //指定裝飾器子元素個(gè)數(shù) protected override int VisualChildrenCount{get;} //布局,添加的子元素需要手動(dòng)布局。 protected override Size ArrangeOverride(Size finalSize); }
2.使用Thumb
因?yàn)門(mén)humb實(shí)現(xiàn)拖動(dòng)比較容易,有相關(guān)事件獲取拖動(dòng)距離。在裝飾器中定義8個(gè)Thumb,對(duì)應(yīng)8個(gè)方位點(diǎn)。
示例代碼如下:
//4條邊 Thumb _leftThumb, _topThumb, _rightThumb, _bottomThumb; //4個(gè)角 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.實(shí)現(xiàn)拖動(dòng)邏輯
在Thumb的DragDelta事件可以獲取拖動(dòng)距離,根據(jù)八個(gè)方位的不同計(jì)算并修改控件的大小。
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) { //1.右側(cè)點(diǎn)HorizontalChange加寬,右邊距減HorizontalChange //2.左側(cè)點(diǎn)HorizontalChange減寬,左邊距加HorizontalChange //3.下側(cè)點(diǎn)VerticalChange加高,下邊距減VerticalChange //4.上側(cè)點(diǎn)VerticalChange減高,上邊距加VerticalChange }
三、完整代碼
代碼如下:
public class GridAdorner : Adorner { //4條邊 Thumb _leftThumb, _topThumb, _rightThumb, _bottomThumb; //4個(gè)角 Thumb _lefTopThumb, _rightTopThumb, _rightBottomThumb, _leftbottomThumb; //布局容器,如果不使用布局容器,則需要給上述8個(gè)控件布局,實(shí)現(xiàn)和Grid布局定位是一樣的,會(huì)比較繁瑣且意義不大。 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內(nèi)部的thumb會(huì)自動(dòng)布局。 _grid.Arrange(new Rect(new Point(-_leftThumb.Width / 2, -_leftThumb.Height / 2), new Size(finalSize.Width + _leftThumb.Width, finalSize.Height + _leftThumb.Height))); return finalSize; } //拖動(dòng)邏輯 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; } }
四、使用示例
示例代碼如下:
xml
<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)); }
效果預(yù)覽:
總結(jié)
以上就是今天要講的內(nèi)容,本文講述了Grid中控件縮放的方法與實(shí)現(xiàn),與Canvas的實(shí)現(xiàn)大部分是相同的,唯一的區(qū)別就是設(shè)置Margin,總得來(lái)說(shuō)還是比較容易實(shí)現(xiàn)的,最終呈現(xiàn)的效果也是比較不錯(cuò)的。
到此這篇關(guān)于C# wpf Grid中實(shí)現(xiàn)控件拖動(dòng)調(diào)整大小的示例代碼的文章就介紹到這了,更多相關(guān)C# wpf Grid拖動(dòng)調(diào)整大小內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQLite之C#版 System.Data.SQLite使用方法
這篇文章主要介紹了SQLite之C#版 System.Data.SQLite使用方法,需要的朋友可以參考下2020-10-10解析c#在未出現(xiàn)異常情況下查看當(dāng)前調(diào)用堆棧的解決方法
本篇文章是對(duì)c#在未出現(xiàn)異常情況下查看當(dāng)前調(diào)用堆棧的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C# WebService發(fā)布以及IIS發(fā)布
這篇文章主要介紹了C# WebService發(fā)布以及IIS發(fā)布的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07