【发布时间】:2019-09-11 06:06:44
【问题描述】:
我正在尝试制作一个在画布上拖动的 UserControl。我正在使用 C# 和 WPF。我在网上看到很多例子,但我只需要最低限度的。
找到一篇文章:《WPF中的可拖动控件》
有人回复:
如果您想手动操作,请使用以下算法:
在 MouseDown 事件中:保存鼠标位置、控件的 TopLeft 位置和这些坐标的 delta(offset),并设置一些布尔字段标志,例如。 IsDragStartted 为真。 在 MouseMove 上检查是否开始拖动并使用鼠标位置和偏移量来计算控件的 TopLeft 位置的新值
在 MouseUp 事件中将 IsDragStarted 设置为 false
我无法应用这个。
公共部分类 UserControl1:UserControl {
private Point startingMousePosition;
private Point endingMousePosition;
private Point startingControlPosition;
bool isDragStarted;
public UserControl1()
{
InitializeComponent();
}
private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if(!isDragStarted)
{
startingControlPosition.X = Canvas.GetLeft(this);
startingControlPosition.Y = Canvas.GetTop(this);
startingMousePosition.X = e.GetPosition(this.Parent as Canvas).X;
startingMousePosition.Y = e.GetPosition(this.Parent as Canvas).Y;
}
}
private void Grid_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
isDragStarted = true;
if (isDragStarted)
{
endingMousePosition.X = e.GetPosition(this.Parent as Canvas).X;
endingMousePosition.Y = e.GetPosition(this.Parent as Canvas).Y;
Canvas.SetLeft(this, endingMousePosition.X - startingControlPosition.X);
Canvas.SetTop(this, endingMousePosition.Y - startingControlPosition.Y);
}
}
}
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
isDragStarted = false;
}
}
这是我的主窗口 WPF 表单代码:
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
UserControl1 userCTL;
public MainWindow()
{
InitializeComponent();
userCTL = new UserControl1();
userCTL.Width = 50;
userCTL.Height = 100;
Canvas.SetTop(userCTL,20);
Canvas.SetLeft(userCTL, 20);
CanvasMain.Children.Add(userCTL);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(userCTL);
if (myAdornerLayer != null)
{
myAdornerLayer.Add(new SimpleCircleAdorner(userCTL));
}
}
}
}
这是我的主窗口的 WPF 代码:
<Window x:Class="WpfApplicationEvent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="374.306" Width="594.271" Loaded="Window_Loaded">
<Grid>
<ScrollViewer Margin="46,23,74,33" PanningMode="Both" HorizontalScrollBarVisibility="Visible">
<Canvas x:Name="CanvasMain" Height="395" Width="506">
</Canvas>
</ScrollViewer>
</Grid>
</Window>
我还尝试放置装饰器,以便最终调整控件的大小。与装饰者一样无处可去,但他们什么也没做。
我在我创建的 UserControl1 中有我所有的拖动控件,我可以拖动它,但是当我再次单击 UserControl1 实例以再次拖动它时,它会重置为 SetTop(0) 和 SetLeft (0) 位置。它跳到那里太奇怪了!我期待将 UserControl1 实例拖到光标的位置。它在第一次尝试时执行,但随后我单击 UserControl1 再次拖动它,它会跳转到 (0,0) 或接近它。
【问题讨论】:
标签: c# wpf canvas draggable drag