WPF 绘制框选框 控件

WPF Canvas 绘制框选框 控件

  • 框选操作在很多设计类软件中经常使用到,使用WPF可以轻松实现框选的效果。本文提供了自定义的,继承自Canvas的框选布局控件及相对应的源代码下载。
  • 绘制框选框使用Border进行绘制。
  • 示例项目已上传到:文件下载

首先是控件的使用效果截图
WPF 绘制框选框 控件_第1张图片
实现思路

直接上代码:

  1. 通过鼠标左键点击事件获取绘制框选的起始位置;
  2. 通过鼠标移动判断要绘制的border大小以及其在Canvas中需要设置的位置;
  3. 位置的计算涉及4种情况,类似坐标系的四个象限位置;
  4. 根据象限位置情况设置框选框的大小及Left和Top坐标。
public class CanvasPanel : Canvas
    {
        Border selectionBorder = new Border()
        {
            Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5563C6F4")),
            BorderThickness = new Thickness(1),
            BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF0C76B8")),
        };

        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            selectionStart = e.GetPosition(this);
            if (!this.Children.Contains(selectionBorder))
            {
                this.Children.Add(selectionBorder);
                this.CaptureMouse();
            }
        }

        Point selectionStart = default;
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                var nowPoint = e.GetPosition(this);

                var offsetX = nowPoint.X - selectionStart.X;
                var offsetY = nowPoint.Y - selectionStart.Y;
                Clear();

                selectionBorder.Width = Math.Abs(offsetX);
                selectionBorder.Height = Math.Abs(offsetY);
                // 分四种情况绘制
                if (offsetX >= 0 && offsetY >= 0)// 右下
                {
                    SetLeft(selectionBorder, selectionStart.X);
                    SetTop(selectionBorder, selectionStart.Y);
                }
                else if (offsetX > 0 && offsetY < 0)// 右上
                {
                    SetLeft(selectionBorder, selectionStart.X);
                    SetBottom(selectionBorder, ActualHeight - selectionStart.Y);

                }
                else if (offsetX < 0 && offsetY > 0)// 左下
                {
                    SetRight(selectionBorder, ActualWidth - selectionStart.X);
                    SetTop(selectionBorder, selectionStart.Y);
                }
                else if (offsetX < 0 && offsetY < 0)// 左上
                {
                    SetRight(selectionBorder, ActualWidth - selectionStart.X);
                    SetBottom(selectionBorder, ActualHeight - selectionStart.Y);
                }


            }
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);
            if (double.IsNaN(GetLeft(selectionBorder)))
            {
                SetLeft(selectionBorder, ActualWidth - GetRight(selectionBorder) - selectionBorder.ActualWidth);
            }
            if (double.IsNaN(GetTop(selectionBorder)))
            {
                SetTop(selectionBorder, ActualHeight - GetBottom(selectionBorder) - selectionBorder.ActualHeight);
            }

            selectionBorder.Width = 0;
            selectionBorder.Height = 0;
            this.Children.Remove(selectionBorder);
            this.ReleaseMouseCapture();
        }

        private void Clear()
        {
            SetLeft(selectionBorder, double.NaN);
            SetRight(selectionBorder, double.NaN);
            SetTop(selectionBorder, double.NaN);
            SetBottom(selectionBorder, double.NaN);
        }
    }

调用代码:

 <Grid>
        <TextBlock Text="按下左键,移动鼠标开始框选" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <local:CanvasPanel Background="Transparent"/>
    </Grid>

你可能感兴趣的:(自定义控件,WPF技术,wpf)