WPF——效果和可视化对象
界面设计
添加
删除
选择移动
选择多个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace WpfApp2
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}//选择移动private bool isDragging = false;private Vector vectorOffset = new Vector();private DrawingVisual selectVisual;//多选private bool isMultSelect = false;private DrawingVisual selectionSquare;private Point selectionSquareTopLeft;private void drawingSurface_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){Point point = e.GetPosition(drawingSurface);if (cmdAdd.IsChecked==true){DrawingVisual visual = new DrawingVisual();this.DrawSquare(visual,point,false);drawingSurface.AddVisual(visual);}if (cmdMove.IsChecked == true){DrawingVisual visual = drawingSurface.GetVisual(point);if (visual != null){isDragging = true;Point topLeftPoint = new Point();topLeftPoint.X = visual.ContentBounds.TopLeft.X + drawingPen.Thickness / 2;topLeftPoint.Y = visual.ContentBounds.TopLeft.Y + drawingPen.Thickness / 2;vectorOffset = topLeftPoint - point;DrawSquare(visual, topLeftPoint,true);if (selectVisual != null && visual != selectVisual){ClearSelection();}selectVisual = visual;}}if (cmdDelete.IsChecked == true){DrawingVisual visual= drawingSurface.GetVisual(point);if (visual != null)drawingSurface.Delete(visual);}if (cmdMultSelect.IsChecked == true){isMultSelect = true;selectionSquare = new DrawingVisual();drawingSurface.AddVisual(selectionSquare);selectionSquareTopLeft = e.GetPosition(drawingSurface);Mouse.Capture(drawingSurface);}}private Brush drawingBrush = Brushes.AliceBlue;private Pen drawingPen= new Pen(Brushes.SteelBlue,3);private Size drawSize = new Size(30,30);private Brush selectDrawingBrush = Brushes.Yellow;private void DrawSquare(DrawingVisual visual, Point point, bool v){using (DrawingContext dt = visual.RenderOpen()){Brush brush = drawingBrush;if (v){brush = selectDrawingBrush;}dt.DrawRectangle(brush, drawingPen,new Rect(point,drawSize));}}private void ClearSelection(){Point topLeftPoint = new Point();topLeftPoint.X = selectVisual.ContentBounds.TopLeft.X + drawingPen.Thickness / 2;topLeftPoint.Y = selectVisual.ContentBounds.TopLeft.Y + drawingPen.Thickness / 2;DrawSquare(selectVisual, topLeftPoint,false);selectVisual = null;}private Brush selectionSquareBrush = Brushes.Transparent;private Pen selectionSquarePen = new Pen(Brushes.Black,2);private void DrawSelectionSquare(Point point1,Point point2){selectionSquarePen.DashStyle = DashStyles.Dash;using (DrawingContext dt = selectionSquare.RenderOpen()){dt.DrawRectangle(selectionSquareBrush,selectionSquarePen,new Rect(point1,point2));}}private void drawingSurface_MouseLeftButtonUp(object sender, MouseButtonEventArgs e){if (isDragging){isDragging = false;}if (isMultSelect){isMultSelect = false;Rect rect = new Rect(selectionSquareTopLeft,e.GetPosition(drawingSurface));RectangleGeometry rectangleGeometry = new RectangleGeometry(rect);List<DrawingVisual> drawingVisuals = drawingSurface.GetVisuals(rectangleGeometry);MessageBox.Show($"选择了{drawingVisuals.Count}个方格");drawingSurface.Delete(selectionSquare);Mouse.Capture(null);}}private void drawingSurface_MouseMove(object sender, MouseEventArgs e){if (isDragging){Point point = e.GetPosition(drawingSurface) + vectorOffset;DrawSquare(selectVisual, point, true);}if (isMultSelect){Point point = e.GetPosition(drawingSurface);DrawSelectionSquare(selectionSquareTopLeft, point);}}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;namespace WpfApp2
{public class DrawingCanvas:Canvas{private List<Visual> visuals = new List<Visual>();protected override int VisualChildrenCount{get{return visuals.Count;}}protected override Visual GetVisualChild(int index){if (index < visuals.Count){return visuals[index];}elsereturn null;}public void AddVisual(Visual visual){visuals.Add(visual);base.AddLogicalChild(visual);base.AddVisualChild(visual);}public DrawingVisual GetVisual(Point point){HitTestResult hitTestResult = VisualTreeHelper.HitTest(this,point);return hitTestResult.VisualHit as DrawingVisual;}public void Delete(Visual visual){visuals.Remove(visual);base.RemoveLogicalChild(visual);base.RemoveVisualChild(visual);}List<DrawingVisual> hits = new List<DrawingVisual>(); public List<DrawingVisual> GetVisuals(Geometry geometry){hits.Clear();HitTestResultCallback hitTestResultCallback = new HitTestResultCallback(hitResultFunc);GeometryHitTestParameters hitTestParameters = new GeometryHitTestParameters(geometry);VisualTreeHelper.HitTest(this,null, hitTestResultCallback, hitTestParameters);return hits;}private HitTestResultBehavior hitResultFunc(HitTestResult result){GeometryHitTestResult geometry = (GeometryHitTestResult)result;DrawingVisual drawingVisual = result.VisualHit as DrawingVisual;if (drawingVisual != null && geometry.IntersectionDetail == IntersectionDetail.FullyInside){hits.Add(drawingVisual);}return HitTestResultBehavior.Continue;}}
}
<Window x:Class="WpfApp2.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp2"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="auto"/><ColumnDefinition/></Grid.ColumnDefinitions><ToolBarTray Orientation="Vertical"><ToolBar><RadioButton Margin="0,3" IsChecked="true" Name="cmdAdd"><StackPanel><Rectangle Width="30" Height="30" Stroke="SteelBlue" StrokeThickness="3" Fill="AliceBlue"/><TextBlock Text="添加"/></StackPanel></RadioButton><RadioButton Margin="0,3" IsChecked="true" Name="cmdMove"><StackPanel><Rectangle Width="30" Height="30" Stroke="SteelBlue" StrokeThickness="3" Fill="AliceBlue"/><TextBlock Text="选择/移动"/></StackPanel></RadioButton><RadioButton Margin="0,3" IsChecked="true" Name="cmdDelete"><StackPanel><Path Stroke="SteelBlue" StrokeThickness="3" StrokeEndLineCap="Round" StrokeStartLineCap="Round" Fill="Red" HorizontalAlignment="Center"><Path.Data><GeometryGroup><PathGeometry><PathFigure StartPoint="0,0"><LineSegment Point="18,18"/></PathFigure><PathFigure StartPoint="18,0"><LineSegment Point="0,18"/></PathFigure></PathGeometry></GeometryGroup></Path.Data></Path><TextBlock Text="删除"/></StackPanel></RadioButton><RadioButton Margin="0,3" IsChecked="true" Name="cmdMultSelect"><StackPanel><Rectangle Width="30" Height="30" Stroke="SteelBlue" StrokeThickness="3" Fill="AliceBlue"/><TextBlock Text="选择多个"/></StackPanel></RadioButton></ToolBar></ToolBarTray><Border Grid.Column="1" Margin="3" BorderBrush="SteelBlue" BorderThickness="1"><local:DrawingCanvas Background="Wheat" x:Name="drawingSurface" MouseLeftButtonDown="drawingSurface_MouseLeftButtonDown"MouseMove="drawingSurface_MouseMove"MouseLeftButtonUp="drawingSurface_MouseLeftButtonUp"/></Border></Grid>
</Window>