質問

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

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

役に立ちましたか?

解決

Thumbを使用した簡単なソリューションです。

  • XAMLおよび分離コードのサブクラスポップアップ
  • 幅/高さを0に設定してThumbを追加します(これはXAMLでも実行できます)
  • ポップアップで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;
        };
    }
}

他のヒント

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));

        }
    }

これを実現するもう 1 つの方法は、ポップアップの配置を MousePoint に設定することです。これにより、ポップアップは最初はマウス カーソルの位置に表示されます。

次に、Thumb または MouseMove イベントを使用して、ポップアップの horizo​​ntaloffset およびverticaloffset を設定できます。これらのプロパティは、ユーザーがポップアップをドラッグすると、ポップアップを元の位置からずらします。

次回ポップアップを使用するときは、必ず 水平オフセットと垂直オフセットをゼロにリセットしてください。

移動が速すぎるとマウスを失う問題は解決できました


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

  

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

     

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


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

だから次のことをしようとすると:
Popup.CaptureMouse()は、ポップアップ自体ではなくラッパーウィンドウをキャプチャしています。代わりに、 Popup.Child.CaptureMouse()を使用すると、実際のポップアップがキャプチャされます。

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

Popup.Child.MouseMove Popup.Child.LostCapture などのように

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

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;
        }
    }

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

Jobi Joy の回答を基に、再利用可能なソリューションを見つけました。既存のコントロール/ページのxaml内のコントロール。名前が異なるスコープを持つため、Xamlに名前を付けて追加することはできませんでした。

    [ContentProperty("Child")]
    [DefaultEvent("Opened")]
    [DefaultProperty("Child")]
    [Localizability(LocalizationCategory.None)]
    public class DraggablePopup : Popup
    {
        public DraggablePopup()
        {
            MouseDown += (sender, e) =>
            {
                Thumb.RaiseEvent(e);
            };

            Thumb.DragDelta += (sender, e) =>
            {
                HorizontalOffset += e.HorizontalChange;
                VerticalOffset += e.VerticalChange;
            };
        }

        /// <summary>
        /// The original child added via Xaml
        /// </summary>
        public UIElement TrueChild { get; private set; }

        public Thumb Thumb { get; private set; } = new Thumb
        {
            Width = 0,
            Height = 0,
        };

        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);

            TrueChild = Child;

            var surrogateChild = new StackPanel();

            RemoveLogicalChild(TrueChild);

            surrogateChild.Children.Add(Thumb);
            surrogateChild.Children.Add(TrueChild);

            AddLogicalChild(surrogateChild);
            Child = surrogateChild;
        }
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top