软件编程
位置:首页>> 软件编程>> C#编程>> C# wpf Grid中实现控件拖动调整大小的示例代码

C# wpf Grid中实现控件拖动调整大小的示例代码

作者:CodeOfCC  发布时间:2023-05-15 17:12:03 

标签:C#,wpf,Grid,拖动

前言

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

一、功能说明

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

C# wpf Grid中实现控件拖动调整大小的示例代码

二、如何实现?

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;
       }
   }

四、使用示例

示例代码如下:

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));
}

效果预览:

C# wpf Grid中实现控件拖动调整大小的示例代码

来源:https://blog.csdn.net/u013113678/article/details/121491198

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com