2

私は WPF と VB.net のプロジェクトで作業しています。オブジェクトの「ドラッグ」を視覚的にシミュレートしたい (ただし、目的のために標準のドラッグ アンド ドロップを使用したくない)。

基本的に、MouseDown イベントで、640x480 のソリッド サイズのグリッド内でマウス カーソルを追跡するラベル オブジェクトがあります (ただし、グリッド外ではありません!)。このグリッドはフルスクリーン ウィンドウの中央に配置されています。繰り返しますが、オブジェクトはグリッドの外でマウスをたどるべきではありません (ここでは "ClipToBounds = True" と推測しています)。

次に、ラベルの MouseUp イベントで、別のオブジェクトの MouseEnter プロパティによって設定されたブール変数の値によって決定されるように、現在の位置に留まるか、元の位置に戻るようにします。

作業が簡単になる場合は、グリッドを簡単にキャンバスに変更できます。それが望ましいと思います。

それで、その長い説明の後、ここに私の質問があります(2倍):

  1. オブジェクト (ラベル) をグリッド/キャンバスの内側ではなく、外側ではなくマウス カーソルに追従させるにはどうすればよいですか? これは、ラベルの MouseDown イベントで発生する必要があります。

  2. オブジェクトを現在の位置に「固定」するにはどうすればよいですか? (これで、自力で元の位置に戻す方法を見つけられるかもしれません.:D)

この目標を最も効率的に達成するのを手伝ってくれる人に賛成票を投じます! どうもありがとうございました。

4

3 に答える 3

6

このようなものはどうですか:

XAML :

<Canvas x:Name="canv" ToolTip="tt one" Width="400" Height="400" Background="Blue">
    <Rectangle x:Name="rec" Fill="Red" Height="50" Width="50" MouseDown="Rectangle_MouseDown" MouseMove="Rectangle_MouseMove" MouseUp="Rectangle_MouseUp" />
</Canvas>

コード ビハインド :

    private bool isDragging;
    private void Rectangle_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        rec.CaptureMouse();
        isDragging = true;

    }

    private void Rectangle_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (isDragging)
        {
            Point canvPosToWindow = canv.TransformToAncestor(this).Transform(new Point(0, 0));

            Rectangle r = sender as Rectangle;
            var upperlimit = canvPosToWindow.Y + (r.Height / 2);
            var lowerlimit = canvPosToWindow.Y + canv.ActualHeight - (r.Height / 2);

            var leftlimit = canvPosToWindow.X + (r.Width / 2);
            var rightlimit = canvPosToWindow.X + canv.ActualWidth - (r.Width / 2);


            var absmouseXpos = e.GetPosition(this).X;
            var absmouseYpos = e.GetPosition(this).Y;

            if ((absmouseXpos > leftlimit && absmouseXpos < rightlimit)
                && (absmouseYpos > upperlimit && absmouseYpos < lowerlimit))
            {
                Canvas.SetLeft(r, e.GetPosition(canv).X - (r.Width / 2));
                Canvas.SetTop(r, e.GetPosition(canv).Y - (r.Height / 2));
            }
        }
    }

    private void Rectangle_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        rec.ReleaseMouseCapture();
        isDragging = false;
    }

このコードは拡張できますが、アイデアは得られたと思います ;)

于 2011-04-14T08:09:13.950 に答える
1

@Brunoに基づいて、これが私の解決策です:

double maxX;
double maxY;

private void OnRectMouseDown(object sender, MouseButtonEventArgs e)
{
    maxX = canv.ActualWidth - rect.Width;
    maxY = canv.ActualHeight - rect.Height;

    rect.CaptureMouse();
    rect.MouseMove += OnRectMouseMove;
    rect.MouseUp += OnRectMouseUp;
}

private void OnRectMouseMove(object sender, MouseEventArgs e)
{
    var pos = e.GetPosition(canv);
    var newX = pos.X - (rect.Width / 2);
    var newY = pos.Y - (rect.Height / 2);

    if (newX < 0) newX = 0;
    if (newX > maxX) newX = maxX;

    if (newY < 0) newY = 0;
    if (newY > maxY) newY = maxY;

    rect.SetValue(Canvas.LeftProperty, newX);
    rect.SetValue(Canvas.TopProperty, newY);

    xVal.Content = (newX / maxX).ToString("F3");
    yVal.Content = (newY / maxY).ToString("F3");
}

private void OnRectMouseUp(object sender, MouseButtonEventArgs e)
{
    rect.ReleaseMouseCapture();
    rect.MouseMove -= OnRectMouseMove;
    rect.MouseUp -= OnRectMouseUp;
}
于 2013-08-21T15:16:24.223 に答える