WPF给界面添加一个异步框选的效果代码

在这里插入图片描述
代码如下:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfAppTest
{
    public class SelectBoxRect
    {
        private Canvas MyCanvas { get; set; }


        private Point _startPoint;
        private Rectangle _drawingRectangle;

        public SelectBoxRect(Canvas canvas)
        {
            MyCanvas = canvas;

            _drawingRectangle = new Rectangle
            {
                Stroke = Brushes.Red,
                StrokeThickness = 2,
                StrokeDashArray = new DoubleCollection(new List<double>() { 4, 2 }),
                Width = 0,
                Height = 0
            };
            MyCanvas.Children.Add(_drawingRectangle);

            canvas.MouseLeftButtonDown += MyCanvas_MouseLeftButtonDown;
            canvas.MouseMove += MyCanvas_MouseMove;
            canvas.MouseLeftButtonUp += MyCanvas_MouseLeftButtonUp;
        }

        private void MyCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _drawingRectangle.Visibility = Visibility.Visible;

            _startPoint = e.GetPosition(MyCanvas);

            Canvas.SetLeft(_drawingRectangle, _startPoint.X);
            Canvas.SetTop(_drawingRectangle, _startPoint.Y);
        }

        private async void MyCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                await UpdateRectangleAsync(e.GetPosition(MyCanvas));
            }
        }

        private void MyCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _drawingRectangle.Visibility = Visibility.Collapsed;
        }

        private async Task UpdateRectangleAsync(Point currentPoint)
        {
            try
            {
                await Task.Run(() =>
                {
                    Application.Current.Dispatcher.Invoke(() =>
                     {
                         double width = currentPoint.X - _startPoint.X;
                         double height = currentPoint.Y - _startPoint.Y;

                         _drawingRectangle.Width = Math.Abs(width);
                         _drawingRectangle.Height = Math.Abs(height);

                         if (width < 0)
                         {
                             Canvas.SetLeft(_drawingRectangle, currentPoint.X);
                         }

                         if (height < 0)
                         {
                             Canvas.SetTop(_drawingRectangle, currentPoint.Y);
                         }
                     });
                });
            }
            catch
            {
            }
        }
    }
}

如何调用:
一行代码调用即可,DrawingContainer指的是界面元素,绘制主题

new SelectBoxRect(DrawingContainer);

XAML代码参考:

<Window x:Class="WpfAppTest.shiliangTest"
        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:WpfAppTest" PreviewMouseWheel="Window_PreviewMouseWheel"
        mc:Ignorable="d"
        Title="shiliangTest" Height="800" Width="1000">
    <Grid>
        <Canvas x:Name="DrawingContainer" Width="800" Height="800" Panel.ZIndex="1" />

    </Grid>
</Window>