wpf - 如何将可拖动的 wpf 弹出窗口设置为关闭后的原始位置?

标签 wpf wpf-controls

我使用了 Stack Overflow 上找到的代码,通过附加行为使 WPF 弹出窗口可拖动。此代码和行为按预期工作。弹出窗口将保持在其拖动位置,直到用户再次移动它。

我现在想做的是让弹出窗口在关闭并重新打开后显示在其原始放置目标位置。我该如何完成这个任务?

原帖:A draggable popup control in 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();
       };
   }
}

预先感谢您的帮助!

最佳答案

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

关于wpf - 如何将可拖动的 wpf 弹出窗口设置为关闭后的原始位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14390142/

相关文章:

wpf - 图像按钮仅在单击图像而不是按钮内部区域时响应

c# - 如何在长时间运行的 *UI* 操作中让 UI 刷新

c# - 在 csv 导入应用程序中防止 sql 注入(inject)

c# - WPF - 将 F 键分配给按钮

wpf - 是否可以在 WPF 中使用 "stylesheet"?

wpf - TextBox 模板填充问题

wpf - 如何为 bool[] 中的值实现 INotifyPropertyChanged 功能?

c# - Caliburn.Micro 让它将 MainView 中的 UserControls 绑定(bind)到他们的 ViewModels

c# - 用于集合 DP 的 WPF TypeConversionAttribute

GridViewColumn 中的 WPF 文本格式设置