界面设计
添加

删除
选择移动
选择多个
csharp
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);
}
}
}
}
csharp
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];
}
else
return 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;
}
}
}
csharp
<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>