【问题标题】:How do I set a draggable wpf popup to its original location once it is closed?关闭后如何将可拖动的 wpf 弹出窗口设置为其原始位置?
【发布时间】:2021-06-07 17:30:20
【问题描述】:

我使用 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();
       };
   }
}

提前感谢您的帮助!

【问题讨论】:

    标签: wpf wpf-controls


    【解决方案1】:

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

    【讨论】:

    • 所提供的代码只需进行一项修改即可工作:我将 AssociatedObject.Closed 更改为 AssociatedObject.Loaded。因为 PlacementTarget 是在我创建弹出窗口时设置的,所以我需要定位此事件,以便弹出窗口知道它从哪里开始。我编辑了答案以反映这种变化。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 2017-09-06
    • 2017-10-28
    • 2023-03-06
    相关资源
    最近更新 更多