如何在 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;
}
}
}
如果你想要真正平滑的拖动,你可以将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
是一种计算从p
到newPos
的距离的方法。
然后,您只需要在释放鼠标时添加最终更新,以便该行最终位于用户期望的位置:
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时购买捕获鼠标,并在释放鼠标按钮后释放鼠标捕获。它工作得很好。再次感谢你们!