我在Window控件上的Canvas中放置了一个简单的UserControl。我已将事件附加到MouseDown,MouseUp和MouseMove,以便我在Canvas周围拖动控件。我也尝试过使用PreviewMouseDown,PreviewMouseUp和PreviewMouseMove,但得到了相同的结果。
这部分有效,但是UserControl移位有一种烦人的行为,一旦我点击UserControl,它的左上角(点0,0)就会移动到光标位置。以下代码仅限于我认为对此问题至关重要的内容。
Window.xaml
<Window x:Class="DragNDropBetweenControls.MainWindow"
xmlns:local="clr-namespace:DragNDropBetweenControls"
Title="MainWindow" MinHeight="350" MinWidth="525">
<Canvas>
<local:UserControl2/>
</Canvas>
</Window>
UserControl.xaml
<UserControl x:Class="DragNDropBetweenControls.UserControl2" >
<Canvas Background="AntiqueWhite">
<Grid Height="25" Width="100" AllowDrop="True" Name="B2"
MouseDown="B2_OnMouseDown"
MouseUp="B2_OnMouseUp"
MouseMove="ui2_MouseMove" >
<Rectangle Fill="Aqua" />
<TextBlock Text="Move Control" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</Canvas>
</UserControl>
UserControl.xaml.cs
public partial class UserControl2 : UserControl
{
private bool IsMouseDown = false;
public UserControl2()
{
InitializeComponent();
}
private void B2_OnMouseDown(object sender, MouseButtonEventArgs e)
{
UIElement ui = (UIElement)sender;
IsMouseDown = true;
ui.CaptureMouse();
}
void ui2_MouseMove (object sender, MouseEventArgs e)
{
Grid b = (Grid)sender;
if (!IsMouseDown)
return;
UIElement parent = (UIElement)b.Parent;
Canvas.SetLeft(b, e.GetPosition(parent).X);
Canvas.SetTop(b, e.GetPosition(parent).Y);
e.Handled = true;
}
private void B2_OnMouseUp(object sender, MouseButtonEventArgs e)
{
IsMouseDown = false;
UIElement ui = (UIElement)sender;
ui.ReleaseMouseCapture();
e.Handled = true;
}
}
所以我想要的是光标和控件在点击和整个移动过程中保持相对于彼此的位置。
非常感谢您的想法/帮助!
答案 0 :(得分:2)
这可能会有所帮助:
public partial class UserControl2 : UserControl
{
bool _pinned;
Point _offset;
public UserControl2()
{
InitializeComponent();
}
private void B2_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var control = (UIElement)sender;
control.CaptureMouse();
_offset = e.GetPosition(control);
_pinned = true;
}
private void ui2_MouseMove(object sender, MouseEventArgs e)
{
if (!_pinned)
return;
var control = (FrameworkElement)sender;
var parent = (FrameworkElement)control.Parent;
Canvas.SetLeft(control, e.GetPosition(parent).X - _offset.X);
Canvas.SetTop(control, e.GetPosition(parent).Y - _offset.Y);
e.Handled = true;
}
private void B2_OnMouseUp(object sender, MouseButtonEventArgs e)
{
_pinned = false;
var control = (UIElement)sender;
control.ReleaseMouseCapture();
e.Handled = true;
}
}
免责声明:我甚至没有尝试编译它。对此感到抱歉,但希望你明白这一点。
答案 1 :(得分:1)
这将确实有效:
private bool IsMouseDown = false;
Point CPos;
private void B2_OnMouseDown(object sender, MouseButtonEventArgs e)
{
UIElement ui = (UIElement)sender;
IsMouseDown = true;
ui.CaptureMouse();
CPos = e.GetPosition(ui);
}
void ui2_MouseMove (object sender, MouseEventArgs e)
{
Grid b = (Grid)sender;
if (!IsMouseDown)
return;
UIElement parent = (UIElement)b.Parent;
Canvas.SetLeft(b, Mouse.GetPosition(parent).X - CPos.X);
Canvas.SetTop(b, Mouse.GetPosition(parent).Y - CPos.Y);
e.Handled = true;
}
private void B2_OnMouseUp(object sender, MouseButtonEventArgs e)
{
IsMouseDown = false;
UIElement ui = (UIElement)sender;
ui.ReleaseMouseCapture();
e.Handled = true;
}