2

我使用在 Stack Overflow 上找到的代码,使用附加的行为使 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 回答