如何在 WPF 中正确拖动和移动一条线

本文关键字:拖动 移动 一条 WPF | 更新日期: 2023-09-27 17:56:29

我可以成功地在WPF的窗口中移动一行,但它无法正常工作。这就像光标比它拖动的线快得多。您可以测试代码以查看是否可以找到其中的问题所在。

public partial class MainWindow : Window
{
    Line line = new Line();
    Point p ; 
    bool isdragging = false;
    public MainWindow()
    {
        InitializeComponent();
        canvas1.Children.Add(line);
        Thickness thickness = new Thickness(101, -11, 362, 250);
        line.Margin = thickness;
        line.Visibility = System.Windows.Visibility.Visible;
        line.StrokeThickness = 4;
        line.Stroke = System.Windows.Media.Brushes.Black;
        line.X1 = 10;
        line.X2 = 200;
        line.Y1 = 0;
        line.Y2 = 70;
        line.MouseDown+=new MouseButtonEventHandler(line_MouseDown);
        line.MouseMove+=new MouseEventHandler(line_MouseMove);
        line.MouseUp+=new MouseButtonEventHandler(line_MouseUp);
    }
    public void line_MouseDown(object sender, MouseButtonEventArgs e)
    {
        isdragging = true;
        p = e.GetPosition(canvas1);
    }
    public void line_MouseMove(object sender, MouseEventArgs e)
    {
        if (isdragging == true && e.LeftButton == MouseButtonState.Pressed)
        {
            line.X1 += e.GetPosition(canvas1).X - p.X;
            line.X2 += e.GetPosition(canvas1).X - p.X;
            line.Y1 += e.GetPosition(canvas1).Y - p.Y;
            line.Y2 += e.GetPosition(canvas1).Y - p.Y;
        }
    }
    public void line_MouseUp(object sender, MouseButtonEventArgs e)
    {
        isdragging = false;
    }
}
}

如何在 WPF 中正确拖动和移动一条线

如果你想要真正平滑的拖动,你可以将Line包裹在一个Thumb中,这样你就可以使用DragDelta事件来计算新位置。

例:

Xaml:

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="233" Width="405" Name="UI">
    <Canvas>
        <Thumb DragDelta="onDragDelta" Canvas.Left="0" Canvas.Top="0" >
            <Thumb.Template>
                <ControlTemplate>
                    <Line X1="10" X2="200" Y1="0" Y2="70" StrokeThickness="4" Stroke="Black"/>
                </ControlTemplate>
            </Thumb.Template>
        </Thumb>
    </Canvas>
</Window>

法典:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    void onDragDelta(object sender, DragDeltaEventArgs e)
    {
        var thumb = sender as Thumb;
        Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange);
        Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange);
    }
}

每次鼠标移动事件后都会移动线条。这将导致代码在鼠标每次轻微移动后尝试在其新位置重新绘制线条 - 甚至下降到单个像素。

您可以跟踪该位置,并且仅在鼠标移动超过一定数量时才重新绘制线条:

public void line_MouseMove(object sender, MouseEventArgs e)
{
    if (isdragging == true && e.LeftButton == MouseButtonState.Pressed)
    {
        Point newPos = e.GetPosition(canvas1);
        if (Size(p, newPos) > 10)
        {
            line.X1 += newPos.X - p.X;
            line.X2 += newPos.X - p.X;
            line.Y1 += newPos.Y - p.Y;
            line.Y2 += newPos.Y - p.Y;
            p = newPos;
        }
    }
}

其中Size是一种计算从pnewPos的距离的方法。

然后,您只需要在释放鼠标时添加最终更新,以便该行最终位于用户期望的位置:

public void line_MouseUp(object sender, MouseButtonEventArgs e)
{
    Point newPos = e.GetPosition(canvas1);
    line.X1 += newPos.X - p.X;
    line.X2 += newPos.X - p.X;
    line.Y1 += newPos.Y - p.Y;
    line.Y2 += newPos.Y - p.Y;
    isdragging = false;
}

谢谢你们的帮助!!我想我解决了这个问题,当我是M时购买捕获鼠标,并在释放鼠标按钮后释放鼠标捕获。它工作得很好。再次感谢你们!