WPF 应用 - 拖拽窗体、控件

1. 拖拽窗体

使用 System.Windows.Window 自带的 DragMove() 方法即可识别窗体拖动。

DragMove();

2. 拖拽控件:复制、移动控件

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="5*"/>
    </Grid.ColumnDefinitions>
    <Grid.Resources>
        <Style TargetType="Rectangle">
            <Setter Property="Width" Value="60"/>
            <Setter Property="Height" Value="20"/>
            <Setter Property="Margin" Value="10"/>
        </Style>
    </Grid.Resources>
 
    <Border Grid.Column="0" BorderBrush="LightSkyBlue" BorderThickness="2" MouseLeftButtonDown="Add_MouseLeftButtonDown">
        <StackPanel x:Name="sp">         
            <Rectangle Fill="#FF113355"/>
            <Rectangle Fill="#FF33AA77"/>
            <Rectangle Fill="#FFBB2200"/>
            <Rectangle Fill="#FFDD0077"/>   
        </StackPanel>
    </Border>

    <Border Grid.Column="1" BorderBrush="LightSkyBlue" BorderThickness="2" MouseLeftButtonDown="Move_MouseLeftButtonDown">
        <Canvas x:Name="cav">
        
        </Canvas>
    </Border>
</Grid>

...

public partial class VisualWindow : Window
{
    public VisualWindow()
    {
        InitializeComponent();
    }
 
    Rectangle SelectedRect { get; set; }

    /// <summary>
    /// 如果点击右侧可新增的矩形,则右侧 Canvas 将新增一个矩形
    /// </summary>
    private void Add_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Point point = e.GetPosition(this.sp);
    
        if (e.Source.GetType() != typeof(Rectangle)) return;
    
        InitRectangle((Rectangle)e.Source);
    
        this.cav.Children.Add(SelectedRect);
    
        this.MouseMove += VisualWindow_MouseMove;
        this.MouseLeftButtonUp += VisualWindow_MouseLeftButtonUp;
    }
    
    /// <summary>
    /// 将 SelectedRect 指向一个新的 Rectangle
    /// </summary>
    private void InitRectangle(Rectangle rect)
    {
        SelectedRect = new Rectangle();
        SelectedRect.Width = rect.Width;
        SelectedRect.Height = rect.Height;
        SelectedRect.Fill = rect.Fill;
        SelectedRect.Opacity = 0;
    }
    
    /// <summary>
    /// 如果目标被拖入指定区域,opacity 设为 0.5,并跟随鼠标,直到鼠标释放或鼠标离开指定区域
    /// </summary>
    private void VisualWindow_MouseMove(object sender, MouseEventArgs e)
    {
        if (SelectedRect == null) return;
    
        Point point = e.GetPosition(this.cav);
    
        if (point.X < 0 || point.Y < 0)
        {
            SelectedRect.Opacity = 0;
            return;
        }
    
        SelectedRect.Opacity = 0.5;
    
        Canvas.SetLeft(SelectedRect, point.X - SelectedRect.Width / 2);
        Canvas.SetTop(SelectedRect, point.Y - SelectedRect.Height / 2);
    }
    
    /// <summary>
    /// 如鼠标离开指定区域(这里可以简单以 SelectedRect.Opacity == 0 作为标记),则移除刚新增的矩形
    /// 如鼠标在指定区域释放,则将新增的矩形停在鼠标释放的位置
    /// </summary>
    private void VisualWindow_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        Point point = e.GetPosition(this.cav);
        bool isMouseOutOfCav = point.X < 0 || point.Y < 0;
    
        if (SelectedRect != null && isMouseOutOfCav)
        {
            this.cav.Children.Remove(SelectedRect);
        }            
    
        SelectedRect.Opacity = 1;
    
        this.MouseMove -= VisualWindow_MouseMove;
        this.MouseLeftButtonUp -= VisualWindow_MouseLeftButtonUp;
    }
    
    /// <summary>
    /// 移动矩形
    /// </summary>
    private void Move_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (e.Source.GetType() != typeof(Rectangle)) return;
    
        SelectedRect = (Rectangle)e.Source;
    
        this.MouseMove += VisualWindow_MouseMove;
        this.MouseLeftButtonUp += VisualWindow_MouseLeftButtonUp;
    }
}

效果:



posted @ 2021-03-08 21:41  鑫茂  阅读(795)  评论(0编辑  收藏  举报