<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們做圖片編輯工具、視訊編輯工具、或者畫板有時需要實現控制元件縮放功能,比如圖片或圖形可以拉伸放大或縮小,實現這種功能通常需要8個點,對應4條邊和4個角,在wpf中通常可以使用裝飾器實現。
8個點方放置在控制元件的8個方位上,通過拖動這些點對控制元件進行拉伸或縮小,示意圖如下:
通過裝飾器的方式新增8個點在控制元件上,這樣既可以不影響控制元件佈局,又可以自由擺放8點控制元件。通過重寫方法,給裝飾新增控制元件。必要的重寫的方法如下面範例所示:
public class CanvasAdorner : Adorner { //獲取裝飾器的元素個數 protected override Visual GetVisualChild(int index); //指定裝飾器子元素個數 protected override int VisualChildrenCount{get;} //佈局,新增的子元素需要手動佈局。 protected override Size ArrangeOverride(Size finalSize); }
因為Thumb實現拖動比較容易,有相關事件獲取拖動距離。在裝飾器中定義8個Thumb,對應8個方位點。
範例程式碼如下:
//4條邊 Thumb _leftThumb, _topThumb, _rightThumb, _bottomThumb; //4個角 Thumb _lefTopThumb, _rightTopThumb, _rightBottomThumb, _leftbottomThumb;
初始化
public CanvasAdorner(UIElement adornedElement) : base(adornedElement) { //初始化thumb _leftThumb = new Thumb(); _leftThumb.HorizontalAlignment = HorizontalAlignment.Left; _leftThumb.VerticalAlignment = VerticalAlignment.Center; _leftThumb.Cursor = Cursors.SizeWE; //其他略... }
在Thumb的DragDelta事件可以獲取拖動距離,根據八個方位的不同計算並修改控制元件的大小。
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) { //1.右側點HorizontalChange加寬 //2.左側點HorizontalChange減寬,加左移 //3.下側點VerticalChange加高 //4.上側點VerticalChange減高,加上移 }
程式碼如下:
public class CanvasAdorner : Adorner { //4條邊 Thumb _leftThumb, _topThumb, _rightThumb, _bottomThumb; //4個角 Thumb _lefTopThumb, _rightTopThumb, _rightBottomThumb, _leftbottomThumb; //佈局容器,如果不使用佈局容器,則需要給上述8個控制元件佈局,實現和Grid佈局定位是一樣的,會比較繁瑣且意義不大。 Grid _grid; UIElement _adornedElement; public CanvasAdorner(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, width, height; if (thumb.HorizontalAlignment == HorizontalAlignment.Left) { left =double.IsNaN( Canvas.GetLeft(c))?0: Canvas.GetLeft(c) + e.HorizontalChange; width = c.Width - e.HorizontalChange; } else { left = Canvas.GetLeft(c); width = c.Width + e.HorizontalChange; } if (thumb.VerticalAlignment == VerticalAlignment.Top) { top = double.IsNaN(Canvas.GetTop(c)) ? 0 : Canvas.GetTop(c) + e.VerticalChange; height = c.Height - e.VerticalChange; } else { top = Canvas.GetTop(c); height = c.Height + e.VerticalChange; } if (thumb.HorizontalAlignment != HorizontalAlignment.Center) { if (width >= 0) { Canvas.SetLeft(c, left); c.Width = width; } } if (thumb.VerticalAlignment != VerticalAlignment.Center) { if (height >= 0) { Canvas.SetTop(c, top); 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
<Canvas Margin="20"> <Border x:Name="border" Width="200" Height="200" Background="Gray" ></Border> </Canvas>
在視窗或控制元件的Loaded事件中新增裝飾器:
cs
private void window_Loaded(object sender, RoutedEventArgs e) { var layer = AdornerLayer.GetAdornerLayer(border); layer.Add(new CanvasAdorner(border)); }
效果預覽:
以上就是今天要講的內容,本文講述了控制元件縮放的方法與實現,都相對較簡單,尤其是實現也是特意精簡了程式碼,比如佈局直接使用Grid控制元件,拖動的邏輯也是較為簡化,最終呈現的效果還是比較不錯的。
到此這篇關於C# wpf Canvas中實現控制元件拖動調整大小的範例的文章就介紹到這了,更多相關C# wpf Canvas控制元件拖動調整大小內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45