WPF で UIElement をドラッグする方法を探しているときに、いくつかのコードに出会い、それを試してみました。Element がクリックされると、マウスにうまく追従しますが、その後のドラッグ イベントでは、Element は元の位置にリセットされます。
xaml のセットアップ: 非常にシンプルで、今までで最もオリジナルな名前の Canvas と Element (この場合は 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 も使用されていませんでした。それがないと、要素はすべての MouseDragEvent で 0,0 の元の位置にリセットされます。そして、それはいたるところにジャンプします。
私の考えでは、Element の現在の位置を MouseUpEvent が発生した場所に何らかの方法で設定することでした。この特定のものは私にとってかなり新しいので、私はさまざまなことをいじっています。例は次のとおりです。 Tile1.TransformToAncestor(Canvas).Transform(mouseLocation);
VisualOffset には必要な情報があることもわかったので、リセットされる前にオブジェクトに何らかの形で既に保存されていますが、何らかの形でアクセスする方法が見つかりませんでした。
Tile1.SetValue(VisualOffset.X = ...);
またTile1Grid.GetValue(VisualOffset);
基本的に、RenderTransform 後に要素の位置をリセットしない方法はありますか?