При поиске способов перетаскивания UIElement в WPF я наткнулся на некоторый код и экспериментировал с ним. Когда элемент нажат, он хорошо следует за мышью, но при последующем событии перетаскивания элемент сбрасывается в исходное положение.
Настройка xaml: очень просто, просто именованный Canvas с самым оригинальным именем и элемент, в данном случае сетка, с именем Tile1.
<Grid>
<Canvas x:Name="Canvas" Width="200" Height="300" Background="LightGray">
<Grid x:Name="Tile1">
<Border BorderBrush="Black" BorderThickness="1" Background="White">
<Control Width="25" Height="25"/>
</Border>
</Grid>
</Canvas>
</Grid>
некоторый код:
public TranslateTransform transPoint;
public Point originPoint;
public MainWindow()
{
InitializeComponent();
Tile1.MouseLeftButtonDown += Tile1_MouseLeftButtonDown;
Tile1.MouseLeftButtonUp += Tile1_MouseLeftButtonUp;
Tile1.MouseMove += Tile1_MouseMove;
}
private void Tile1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var myLocation = e.GetPosition(Canvas);
originPoint = new Point(myLocation.X, myLocation.Y);
transPoint = new TranslateTransform(originPoint.X, originPoint.Y);
}
private void Tile1_MouseMove(object sender, MouseEventArgs e)
{
var mouseLocation = e.GetPosition(Canvas);
if (e.LeftButton == MouseButtonState.Pressed)
{
transPoint.X = (mouseLocation.X - originPoint.X);
transPoint.Y = (mouseLocation.Y - originPoint.Y);
Tile1.RenderTransform = transPoint;
}
}
private void Tile1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var mouseLocationOnCanvas = e.GetPosition(Canvas);
var mouseLocationOnTile = e.GetPosition(Tile1);
//attempting to account for offset of mouse on the Tile:
var newX = mouseLocationOnCanvas.X - mouseLocationOnTile.X;
var newY = mouseLocationOnCanvas.Y - mouseLocationOnTile.Y;
Tile1.Margin = new Thickness(newX, newY, 0, 0);
}
В исходном примере (ссылка добавлена здесь) событие MouseUpEvent даже не использовалось. Без него мой элемент просто сбрасывается в исходное положение на 0,0 при каждом MouseDragEvent. И с ним он будет прыгать повсюду.
Моя мысль заключалась в том, чтобы каким-то образом установить текущую позицию элемента в том месте, где произошло событие MouseUpEvent. Я возился с разными вещами, так как этот конкретный материал для меня довольно новый. Примеры: Tile1.TransformToAncestor(Canvas).Transform(mouseLocation);
Я также обнаружил, что в VisualOffset есть нужная мне информация, поэтому она каким-то образом уже сохранена в объекте до сброса, но я не нашел способа получить к ней доступ в какой-либо форме. Tile1.SetValue(VisualOffset.X = ...);
или Tile1Grid.GetValue(VisualOffset);
Итак, есть ли способ не сбрасывать позицию элемента после RenderTransform?