我是 C# 的新手。 我一直在使用 MouseDown 和 MouseMove 在 C# (wpf) 中进行测试。尝试创建一个简单的椭圆,可以在画布内通过单击和移动鼠标来拖动它。 一切都很好,直到我运行代码,我看到当我拖动椭圆时它会抖动。 我知道对某些人来说这不是问题,但对我来说却是。 接下来是我使用的 xaml 代码。
<Canvas>
<Ellipse x:Name="circulito" Fill="#FFFDC347" Height="100" Stroke="Black" Width="100"
MouseDown="circulito_MouseDown"
MouseMove="circulito_MouseMove"/>
</Canvas>
接下来是 c# 中的代码。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
Point coor;
Point coorPutin;
private void circulito_MouseDown(object sender, MouseButtonEventArgs e)
{
coor.X = Canvas.GetLeft(this);
coor.Y = Canvas.GetTop(this);
}
private void circulito_MouseMove(object sender, MouseEventArgs e)
{
coorPutin = e.GetPosition(circulito);
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
Canvas.SetLeft(circulito, coor.X + coorPutin.X);
Canvas.SetTop(circulito, coor.Y + coorPutin.Y);
}
}
一切都很好,直到我运行代码,我看到当我拖动椭圆时它会抖动
这是因为您的 circulito_MouseMove
例程。您不需要检查按钮是否关闭,也不需要检查您是否正在尝试设置画布,这行不通,您需要设置元素(椭圆)TopProperty
和 LeftProperty
。请参阅下面的工作解决方案。
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private Ellipse _ellipse;
private Point? _coor;
public MainWindow() { InitializeComponent(); }
private void circulito_MouseDown(object sender, MouseButtonEventArgs e)
{
_ellipse = sender as Ellipse;
_coor = e.GetPosition(_ellipse);
}
private void circulito_MouseMove(object sender, MouseEventArgs e)
{
if (_ellipse == null)
return;
_ellipse.SetValue(Canvas.LeftProperty, e.GetPosition(this).X - _coor.Value.X);
_ellipse.SetValue(Canvas.TopProperty, e.GetPosition(this).Y - _coor.Value.Y);
}
private void circulito_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) => _ellipse = null;
}
MainWindow.xaml
<Window x:Class="WpfApp12.MainWindow"
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"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d"
MouseMove="circulito_MouseMove"
>
<Canvas>
<Ellipse x:Name="circulito"
Width="100"
Height="100"
Fill="#FFFDC347"
Stroke="Black"
MouseLeftButtonDown="circulito_MouseDown"
MouseLeftButtonUp="circulito_MouseLeftButtonUp"
MouseMove="circulito_MouseMove"
/>
</Canvas>
</Window>
请注意,在 MainWindow.xaml
Window
元素中,您还需要处理 MouseMove
事件...
MouseMove="circulito_MouseMove"
我认为在 MouseMove
中您应该使用鼠标在画布中的位置。因此给它一个名字
<Canvas x:Name="canvas">
然后你可以用
设置椭圆的位置public void circulito_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed) {
var coorPutin = e.GetPosition(canvas);
Canvas.SetLeft(circulito, coorPutin.X - coor.X);
Canvas.SetTop(circulito, coorPutin.Y - coor.Y);
}
}
此外,您必须从 MouseDown
中减去您得到的初始位置,因为您想将椭圆的上/左位置设置在鼠标位置的上方和左侧,以保持鼠标位置的相对位置鼠标光标位于椭圆中。
Canvas.GetLeft(this);
如果尚未初始化,将返回 NaN
(不是数字)。因此最好使用
public void circulito_MouseDown(object sender, MouseButtonEventArgs e)
{
coor = e.GetPosition(circulito);
}
非常感谢 Codexer 回答我。 xaml 代码保持不变。 最后只需将c#代码改成如下即可。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
Point coor;
private void circulito_MouseDown(object sender, MouseButtonEventArgs e)
{
coor = e.GetPosition(circulito);
}
private void circulito_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
circulito.SetValue(Canvas.LeftProperty, e.GetPosition(this).X - coor.X);
circulito.SetValue(Canvas.TopProperty, e.GetPosition(this).Y - coor.Y);
}
}
}