WPF ポップアップ コントロールは素晴らしいですが、私の意見では多少制限があります。ポップアップが開いているときにポップアップを「ドラッグ」する方法はありますか (ウィンドウの DragMove() メソッドのように)?
これは大きな問題なく実行できますか、それとも popup クラスの代わりを自分で作成する必要がありますか? ありがとう
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));
}
}
Thumb を使用した簡単なソリューションを次に示します。
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;
};
}
}
動きが速すぎるとマウスが失われる問題が解決される可能性があります
これは msdn から取得されます。
新しいウィンドウには、ポップアップの子コンテンツが含まれています。
Popup コントロールは、子コンテンツへの参照を論理的な子として保持します。新しいウィンドウが作成されると、Popup のコンテンツはウィンドウの視覚的な子になり、Popup の論理的な子のままになります。逆に、Popup はその Child コンテンツの論理的な親のままです。
つまり、ポップアップの子はスタンドアロン ウィンドウに表示されます。
したがって、次のことを試みると
Popup.CaptureMouse()
、ポップアップ自体ではなく、ラッパーウィンドウがキャプチャされます。代わりにPopup.Child.CaptureMouse()
、実際のポップアップをキャプチャします。
その他のすべてのイベントは、 を使用して登録する必要がありますPopup.Child
。
Popup.Child.MouseMove
など_ Popup.Child.LostCapture
_
これはテスト済みで、完全に正常に動作します
これについて他の人が述べたことに反して、私はジョビ・ジョイの答えに100%同意します(これは正直に受け入れられた答えであるはずです)。回答の解決策がメモリの断片化を引き起こすというコメントを見ました。新しい構造体を作成してもメモリの断片化がまったく発生しないため、これは不可能です。実際、構造体はスタックに割り当てられるため、構造体を使用するとメモリが節約されます。さらに、これは実際にはポップアップの位置を変更する正しい方法だと思います (結局、Microsoft は何らかの理由で PlacementRectangle プロパティを追加しました)。したがって、ハックではありません。ただし、Thumb を追加して、ユーザーが常に Popup をキャンバスに配置することを期待することは、信じられないほどハックであり、常に実用的な解決策とは限りません。
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;
}
}
これは私のウィンドウをドラッグするのに機能しますが、マウスを速く動かすと言われたように、ウィンドウから出てイベントの発生を停止します。言うまでもなく、ドラッグはまったくスムーズではありません。あまりにも速くドラッグしたときにそれを失うことなく、正しくスムーズにドラッグする方法を知っている人はいますか? 私のような初心者がコードで迷子になるチュートリアル全体を除いて、可能であれば簡単な例を投稿してください。ありがとう!