2

スタック オーバーフローで見つかったコードを使用して、添付されたビヘイバーを使用して WPF ポップアップをドラッグ可能にしました。このコードと動作は期待どおりに機能します。ポップアップは、ユーザーが再度移動するまで、ドラッグされた位置に留まります。

今やりたいことは、ポップアップを閉じて再度開いたときに、元の配置ターゲットの場所に表示することです。このタスクを達成するにはどうすればよいですか?

元の投稿: wpf のドラッグ可能なポップアップ コントロール

Rick Sladkey によって書かれた回答コード: https://stackoverflow.com/a/4784977/1286413

ポップアップの XAML は次のとおりです。

<Grid>
   <StackPanel>
       <TextBox x:Name="textBox1" Width="200" Height="20"/>
   </StackPanel>
   <Popup PlacementTarget="{Binding ElementName=textBox1}" IsOpen="{Binding IsKeyboardFocused, ElementName=textBox1, Mode=OneWay}">
       <i:Interaction.Behaviors>
           <local:MouseDragPopupBehavior/>
       </i:Interaction.Behaviors>
       <TextBlock Background="White">
           <TextBlock.Text>Sample Popup content.</TextBlock.Text>
       </TextBlock>
   </Popup>
</Grid>

彼が書いた AttachedBehavior は次のとおりです。

public class MouseDragPopupBehavior : Behavior<Popup>
{
   private bool mouseDown;
   private Point oldMousePosition;

   protected override void OnAttached()
   {
       AssociatedObject.MouseLeftButtonDown += (s, e) =>
       {
           mouseDown = true;
           oldMousePosition = AssociatedObject.PointToScreen(e.GetPosition(AssociatedObject));
           AssociatedObject.Child.CaptureMouse();
       };
       AssociatedObject.MouseMove += (s, e) =>
       {
           if (!mouseDown) return;
           var newMousePosition = AssociatedObject.PointToScreen(e.GetPosition(AssociatedObject));
           var offset = newMousePosition - oldMousePosition;
           oldMousePosition = newMousePosition;
           AssociatedObject.HorizontalOffset += offset.X;
           AssociatedObject.VerticalOffset += offset.Y;
       };
       AssociatedObject.MouseLeftButtonUp += (s, e) =>
       {
           mouseDown = false;
           AssociatedObject.Child.ReleaseMouseCapture();
       };
   }
}

助けてくれてありがとう!

4

1 に答える 1

2

OnAttached で、ポップアップの位置を保存するハンドラーを Closed に追加し、ポップアップをその位置に戻す別のハンドラーを Opened に追加します。

public class MouseDragPopupBehavior : Behavior<Popup>
{
    private bool mouseDown;
    private Point oldMousePosition;

    private bool useSavedPosition;
    private Point savedPosition;

    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonDown += (s, e) =>
        {
            mouseDown = true;
            oldMousePosition = AssociatedObject.PointToScreen(e.GetPosition(AssociatedObject));
            AssociatedObject.Child.CaptureMouse();
        };
        AssociatedObject.MouseMove += (s, e) =>
        {
            if (!mouseDown) return;
            var newMousePosition = AssociatedObject.PointToScreen(e.GetPosition(AssociatedObject));
            var offset = newMousePosition - oldMousePosition;
            oldMousePosition = newMousePosition;
            AssociatedObject.HorizontalOffset += offset.X;
            AssociatedObject.VerticalOffset += offset.Y;
        };
        AssociatedObject.MouseLeftButtonUp += (s, e) =>
        {
            mouseDown = false;
            AssociatedObject.Child.ReleaseMouseCapture();
        };

        AssociatedObject.Opened += (s, e) =>
        {
            if (!useSavedPosition) return;
            AssociatedObject.HorizontalOffset = savedPosition.X;
            AssociatedObject.VerticalOffset = savedPosition.Y;
        };

        AssociatedObject.Loaded += (s, e) =>
        {
            savedPosition = new Point(AssociatedObject.HorizontalOffset, AssociatedObject.VerticalOffset);
            useSavedPosition = true;
        };
    }
}
于 2013-01-18T00:06:17.223 に答える