2

私は基本的に、タイトル バー (グリッド自体) をドラッグして場所を変更できる単純なフローティング パネルを作成しています。しかし、私はそれを働かせることができません!MouseEventArgs.GetPosition間違ったポイントを返すようです。ここで何が欠けていますか?

public class FloatingPanel : Grid
    {
        Grid gridTitle;

        bool dragging = false;
        Point lastPos;

        public FloatingPanel(UserControl gadget)
        {
            this.MouseMove += FloatingPanel_MouseMove;

            gridTitle = new Grid();
            gridTitle.Height = 25;
            gridTitle.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            gridTitle.Background = Brushes.Cyan;
            gridTitle.MouseLeftButtonDown += gridTitle_MouseLeftButtonDown;
            gridTitle.MouseLeftButtonUp += gridTitle_MouseLeftButtonUp;
            this.Children.Add(gridTitle);

            this.Height = gadget.Height + 25;
            this.Width = gadget.Width;

            gadget.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
            this.Children.Add(gadget);
        }

        void gridTitle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            dragging = false;
        }

        void gridTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            lastPos = Mouse.GetPosition(this);
            dragging = true;
        }

        void FloatingPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if(dragging)
            {
                Vector delta = e.GetPosition(this) - lastPos;
                this.Margin = new Thickness(this.Margin.Left + delta.X, this.Margin.Top + delta.Y, this.Margin.Right, this.Margin.Bottom);
                lastPos = e.GetPosition(this);
            }
        }
    }  

画面上の位置を指定するSystem.Windows.Forms.Cursor.Positionandも使用してみました。System.Windows.Forms.Control.MousePositionしかし、運がありません。
解決策:この問題は 3 つの修正によって解決されました (Sphinxxx が指摘したように):
-MouseEventArgs.GetPosition(null)の代わりに使用MouseEventArgs.GetPosition(this)
- マウスのキャプチャと解放、mousedownおよびを使用したmouseupイベント - グリッドの水平方向と垂直方向の配置の設定。(これは私には奇妙に思えます。うなずきの配置を設定すると問題が発生するのはなぜですか?)Mouse.Capture(gridTitle)Mouse.Capture(null)

4

1 に答える 1

2

では_MouseMove、 を使用して動きを計算しようとしていますがe.GetPosition(this)、それはマウス ポインタの位置をに対して相対的にGrid取得するだけです。Windowグリッドがどれだけ移動する必要があるかを知るために、含まれているものなど、他の UI 要素との相対的な位置を見つける必要があります。

との両方で ( this ではなく null )をe.GetPosition(null)試し正しいsを計算してください。_MouseLeftButtonDown_MouseMovedelta

この記事では、違いについて説明します: 特定の要素に対するマウスの位置を取得する

編集:より堅牢FloatingPanel:

コンストラクターでは、ガジェットを 2 つの別々の に配置することで、ガジェットがタイトル バーの上に表示されるのを回避しますRowDefinition(幅と高さは WPF に処理させます)。

public FloatingPanel(FrameworkElement gadget)
{
    gridTitle = new Grid();
    gridTitle.Height = 25;
    gridTitle.Background = Brushes.Cyan;

    gridTitle.MouseLeftButtonDown += gridTitle_MouseLeftButtonDown;
    gridTitle.MouseMove += gridTitle_MouseMove;
    gridTitle.MouseLeftButtonUp += gridTitle_MouseLeftButtonUp;

    //Create two grid rows - one to hold the title bar..
    this.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
    Grid.SetRow(gridTitle, 0);
    this.Children.Add(gridTitle);

    //..and one two hold the gadget:
    this.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
    Grid.SetRow(gadget, 1);
    this.Children.Add(gadget);
}

..ButtonDown/ハンドラーで、..ButtonUpタイトル バーがマウスの動きを「キャプチャ」(および解放) するようにして、移動が速すぎてもマウス ポインターが「滑り落ち」ないようにします。

void gridTitle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    //Relese a previous capture:
    Mouse.Capture(null);
    dragging = false;
}

void gridTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    lastPos = Mouse.GetPosition(null);

    //Capture the mouse to ensure we get all future mouse movements:
    Mouse.Capture(gridTitle);
    dragging = true;
}

EDIT 2:なしの代替Mouse.Capture():

...
gridTitle.MouseLeftButtonDown += gridTitle_MouseLeftButtonDown;

//gridTitle.MouseMove += gridTitle_MouseMove;

//The parent Window isn't available yet here in the constructor,
//so we must wait for our Loaded event to hook it up:
this.Loaded += (s, e) => { Window.GetWindow(this).MouseMove += gridTitle_MouseMove; };

gridTitle.MouseLeftButtonUp += gridTitle_MouseLeftButtonUp;
...
于 2013-12-31T17:22:13.293 に答える