【问题标题】:WPF DragMove() causes issuesWPF DragMove() 导致问题
【发布时间】:2018-09-14 17:41:02
【问题描述】:

我正在尝试找出我所面临的问题是否有一个优雅的解决方案。

所以基本上,我设计了一个完全可以通过拖动移动的无边框加载启动画面。我发现如果初始屏幕通过 Hide() 隐藏,然后通过 ShowDialog() 显示一个窗口,所有者设置为初始屏幕,就会发生这种情况。事情变得非常有问题,但前提是您处于中间拖动状态(按下鼠标左键)。您将无法单击或移动任何内容,甚至 Visual Studio 也会变得无响应,除非您明确地按 alt-tab 键退出应用程序。

考虑到我知道何时要生成窗口,我在想也许有办法取消 DragMove 操作,但我没有运气。我发现 DragMove 是同步的,所以我猜它必须从不同的线程或事件回调中取消。

编辑:

public partial class Window_Movable : Window
{
    public Window_Movable()
    {
        InitializeComponent();
    }

    public Boolean CanMove { get; set; } = true;

    private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (CanMove == false)
            return;

        Task.Factory.StartNew(() => {
            System.Threading.Thread.Sleep(1000);

            Dispatcher.Invoke(() => {
                Hide();
                new Window_Movable() {
                    Title = "MOVABLE 2",
                    CanMove = false,
                    Owner = this
                }.ShowDialog();
            });
        });

        DragMove();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("DING");
    }
}

【问题讨论】:

    标签: c# .net wpf


    【解决方案1】:

    我遇到了同样的问题,发现 DragMove() 方法有问题。 https://groups.google.com/forum/#!topic/wpf-disciples/7OcuXrf2whc

    为了解决我决定拒绝使用它并实现移动逻辑。 我结合了一些解决方案 https://www.codeproject.com/Questions/284995/DragMove-problem-help-plsC# WPF Move the window

            private bool _inDrag;
            private Point _anchorPoint;
            private bool _iscaptured;
    
            private void AppWindowWindowOnMouseMove(object sender, MouseEventArgs e)
            {
                if (!_inDrag)
                    return;
    
                if (!_iscaptured)
                {
                    CaptureMouse();
                    _iscaptured = true;
                }
    
                var mousePosition = e.GetPosition(this);
                var mousePositionAbs = new Point
                {
                    X = Convert.ToInt16(_appWindowWindow.Left) + mousePosition.X,
                    Y = Convert.ToInt16(_appWindowWindow.Top) + mousePosition.Y
                };
                _appWindowWindow.Left = _appWindowWindow.Left + (mousePositionAbs.X - _anchorPoint.X);
                _appWindowWindow.Top = _appWindowWindow.Top + (mousePositionAbs.Y - _anchorPoint.Y);
                _anchorPoint = mousePositionAbs;
            }
    
            private void AppWindowWindowOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                if (_inDrag)
                {
                    _inDrag = false;
                    _iscaptured = false;
                    ReleaseMouseCapture();
                }
            }
    
            private void AppWindowWindowOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                _anchorPoint = e.GetPosition(this);
                _anchorPoint.Y = Convert.ToInt16(_appWindowWindow.Top) + _anchorPoint.Y;
                _anchorPoint.X = Convert.ToInt16(_appWindowWindow.Left) + _anchorPoint.X;
                _inDrag = true;
            }
    

    我昨天晚上都在寻找一个更hacky但更实用的解决方案。支持最大化状态,不需要手动坐标计算。

        private bool _mRestoreForDragMove;
        private void OnAppWindowWindowOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                if (_appWindowWindow.ResizeMode != ResizeMode.CanResize &&
                    _appWindowWindow.ResizeMode != ResizeMode.CanResizeWithGrip)
                {
                    return;
                }
    
                _appWindowWindow.WindowState = _appWindowWindow.WindowState == WindowState.Maximized
                    ? WindowState.Normal
                    : WindowState.Maximized;
            }
            else
            {
                _mRestoreForDragMove = _appWindowWindow.WindowState == WindowState.Maximized;
    
                SafeDragMoveCall(e);
            }
        }
    
        private void SafeDragMoveCall(MouseEventArgs e)
        {
            Task.Delay(100).ContinueWith(_ =>
            {
                Dispatcher.BeginInvoke((Action)
                    delegate
                    {
                        if (Mouse.LeftButton == MouseButtonState.Pressed)
                        {
                            _appWindowWindow.DragMove();
                            RaiseEvent(new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left)
                            {
                                RoutedEvent = MouseLeftButtonUpEvent
                            });
                        }
                    });
            });
        }
    
        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (_mRestoreForDragMove)
            {
                _mRestoreForDragMove = false;
    
                var point = PointToScreen(e.MouseDevice.GetPosition(this));
    
                _appWindowWindow.Left = point.X - (_appWindowWindow.RestoreBounds.Width * 0.5);
                _appWindowWindow.Top = point.Y;
    
                _appWindowWindow.WindowState = WindowState.Normal;
    
                _appWindowWindow.DragMove();
    
                SafeDragMoveCall(e);
            }
        }
    
        private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _mRestoreForDragMove = false;
        }
    

    问题是在短暂延迟后发送 LeftMouseButtonUp 事件以避免被 DragMove() 阻塞

    最后解决的来源: DragMove() and Maximize C# WPF - DragMove and click

    【讨论】:

      【解决方案2】:

      还有一种完全不同的解决方案。要使窗口可移动,您可以使用 WindowChrome 的 CaptionHeight。 即

         var windowChrome = 
                  WindowChrome.GetWindowChrome(appWindow.Window);
                  windowChrome.CaptionHeight = MainWindowToolbar.Height;
          WindowChrome.SetWindowChrome(appWindow.Window, windowChrome);
      

      但您还应该为窗口中的所有控件设置附加属性WindowChrome.IsHitTestVisibleInChrome="True"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 2014-01-10
        • 2014-08-02
        • 1970-01-01
        • 1970-01-01
        • 2020-12-11
        • 2011-10-15
        相关资源
        最近更新 更多