21

WPF ポップアップ コントロールは素晴らしいですが、私の意見では多少制限があります。ポップアップが開いているときにポップアップを「ドラッグ」する方法はありますか (ウィンドウの DragMove() メソッドのように)?

これは大きな問題なく実行できますか、それとも popup クラスの代わりを自分で作成する必要がありますか? ありがとう

4

7 に答える 7

19

PopUp の DragMove はありません。ちょっとした回避策ですが、これに追加できる改善点はたくさんあります。

<Popup x:Name="pop" IsOpen="True" Height="200" Placement="AbsolutePoint"  Width="200">
   <Rectangle Stretch="Fill" Fill="Red"/>            
</Popup>

コード ビハインドで、この mousemove イベントを追加します。

   pop.MouseMove += new MouseEventHandler(pop_MouseMove);

   void pop_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            pop.PlacementRectangle = new Rect(new Point(e.GetPosition(this).X,
                e.GetPosition(this).Y),new Point(200,200));

        }
    }
于 2008-10-21T15:07:32.577 に答える
18

Thumb を使用した簡単なソリューションを次に示します。

  • XAML と分離コードでポップアップをサブクラス化する
  • 幅/高さが 0 に設定された Thumb を追加します (これは XAML でも実行できます)。
  • Popup で MouseDown イベントをリッスンし、Thumb で同じイベントを発生させます。
  • DragDelta でポップアップを移動

XAML:

<Popup x:Class="PopupTest.DraggablePopup" ...>
    <Canvas x:Name="ContentCanvas">

    </Canvas>
</Popup>

C#:

public partial class DraggablePopup : Popup 
{
    public DraggablePopup()
    {
        var thumb = new Thumb
        {
            Width = 0,
            Height = 0,
        };
        ContentCanvas.Children.Add(thumb);

        MouseDown += (sender, e) =>
        {
            thumb.RaiseEvent(e);
        };

        thumb.DragDelta += (sender, e) =>
        {
            HorizontalOffset += e.HorizontalChange;
            VerticalOffset += e.VerticalChange;
        };
    }
}
于 2011-11-17T16:26:23.437 に答える
2

動きが速すぎるとマウスが失われる問題が解決される可能性があります


これは msdn から取得されます。

新しいウィンドウには、ポップアップの子コンテンツが含まれています。

Popup コントロールは、子コンテンツへの参照を論理的な子として保持します。新しいウィンドウが作成されると、Popup のコンテンツはウィンドウの視覚的な子になり、Popup の論理的な子のままになります。逆に、Popup はその Child コンテンツの論理的な親のままです。


つまり、ポップアップの子はスタンドアロン ウィンドウに表示されます。

したがって、次のことを試みると
Popup.CaptureMouse()、ポップアップ自体ではなく、ラッパーウィンドウがキャプチャされます。代わりにPopup.Child.CaptureMouse()、実際のポップアップをキャプチャします。

その他のすべてのイベントは、 を使用して登録する必要がありますPopup.Child

Popup.Child.MouseMoveなど_ Popup.Child.LostCapture_

これはテスト済みで、完全に正常に動作します

于 2011-12-09T18:28:52.977 に答える
1

これについて他の人が述べたことに反して、私はジョビ・ジョイの答えに100%同意します(これは正直に受け入れられた答えであるはずです)。回答の解決策がメモリの断片化を引き起こすというコメントを見ました。新しい構造体を作成してもメモリの断片化がまったく発生しないため、これは不可能です。実際、構造体はスタックに割り当てられるため、構造体を使用するとメモリが節約されます。さらに、これは実際にはポップアップの位置を変更する正しい方法だと思います (結局、Microsoft は何らかの理由で PlacementRectangle プロパティを追加しました)。したがって、ハックではありません。ただし、Thumb を追加して、ユーザーが常に Popup をキャンバスに配置することを期待することは、信じられないほどハックであり、常に実用的な解決策とは限りません。

于 2021-07-26T13:06:53.793 に答える
0
Private Point startPoint;

 private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {

        startPoint = e.GetPosition(null);
    }
private void Window_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            Point relative = e.GetPosition(null);
            Point AbsolutePos = new Point(relative.X + this.Left, relative.Y + this.Top);
            this.Top = AbsolutePos.Y - startPoint.Y;
            this.Left = AbsolutePos.X - startPoint.X;
        }
    }

これは私のウィンドウをドラッグするのに機能しますが、マウスを速く動かすと言われたように、ウィンドウから出てイベントの発生を停止します。言うまでもなく、ドラッグはまったくスムーズではありません。あまりにも速くドラッグしたときにそれを失うことなく、正しくスムーズにドラッグする方法を知っている人はいますか? 私のような初心者がコードで迷子になるチュートリアル全体を除いて、可能であれば簡単な例を投稿してください。ありがとう!

于 2011-04-30T18:28:11.910 に答える