8

我有一个无标题窗口,因为我想创建自己的窗口样式。

标题和最小化、最大化和关闭按钮位于停靠面板中。我添加了以下事件处理程序来最大化、恢复和拖动窗口。

当窗口最大化时,问题就来了。

我发现,每当我单击标题时,就会恢复。当我只希望它被双击或拖动时恢复。我可以看到它为什么会发生,但不确定如何解决这个问题。

    public void TITLEBAR_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DockPanel dp = (DockPanel)sender;
        Window parentWindow = Window.GetWindow(dp);
        bool doubleClick = IsDoubleClick(sender, e);

        if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed && !doubleClick)
        {


            if (parentWindow.WindowState == WindowState.Maximized)
            {
                double mouseX = e.GetPosition(parentWindow).X;
                double width = parentWindow.RestoreBounds.Width;
                System.Drawing.Rectangle screenBounds = getCurrentScreenBounds(parentWindow);
                double x = screenBounds.Left + (mouseX - ((width / 100.00) * ((100.00 / screenBounds.Width) * mouseX)));

                if (x < 0)
                {
                    x = 0;
                }
                else
                {
                    if (x + width > screenBounds.Left + screenBounds.Width)
                    {
                        x = screenBounds.Left + screenBounds.Width - width;
                    }
                }

                parentWindow.Left = x;
                parentWindow.Top = screenBounds.Top;
                parentWindow.WindowState = System.Windows.WindowState.Normal;
            }

            parentWindow.DragMove();
            //MessageBox.Show("");
        }

        if (doubleClick)
        {
            if (parentWindow.WindowState == System.Windows.WindowState.Maximized)
            {
                parentWindow.WindowState = System.Windows.WindowState.Normal;
            }
            else
            {
                parentWindow.WindowState = System.Windows.WindowState.Maximized;
            }
        }
    }

随着这个类:

public static class MouseButtonHelper
{
    private const long k_DoubleClickSpeed = 500;
    private const double k_MaxMoveDistance = 10;

    private static long _LastClickTicks = 0;
    private static System.Windows.Point _LastPosition;
    private static WeakReference _LastSender;

    public static bool IsDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        System.Windows.Point position = e.GetPosition(null);
        long clickTicks = DateTime.Now.Ticks;
        long elapsedTicks = clickTicks - _LastClickTicks;
        long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond;
        bool quickClick = (elapsedTime <= k_DoubleClickSpeed);
        bool senderMatch = (_LastSender != null && sender.Equals(_LastSender.Target));

        if (senderMatch && quickClick && position.Distance(_LastPosition) <= k_MaxMoveDistance)
        {
            // Double click!
            _LastClickTicks = 0;
            _LastSender = null;
            return true;
        }

        // Not a double click
        _LastClickTicks = clickTicks;
        _LastPosition = position;
        if (!quickClick)
            _LastSender = new WeakReference(sender);
        return false;
    }


    private static double Distance(this System.Windows.Point pointA, System.Windows.Point pointB)
    {
        double x = pointA.X - pointB.X;
        double y = pointA.Y - pointB.Y;
        return Math.Sqrt(x * x + y * y);
    }
}

这可以解决当前屏幕的范围。

public static class WindowHelper
{
    public static System.Drawing.Rectangle getCurrentScreenBounds(System.Windows.Window pWnd)
    {
        System.Windows.Forms.Screen parentScreen = GetCurrentScreen(pWnd);

        if (parentScreen == null)
        {
            return System.Windows.Forms.Screen.PrimaryScreen.Bounds;
        }

        return parentScreen.Bounds;
    }

    private static System.Windows.Forms.Screen GetCurrentScreen(System.Windows.Window pWnd)
    {
        System.Drawing.Rectangle intersectingRect = new System.Drawing.Rectangle();
        System.Drawing.Rectangle windowRect = new System.Drawing.Rectangle(Convert.ToInt32(pWnd.Left), Convert.ToInt32(pWnd.Top), Convert.ToInt32(pWnd.Width), Convert.ToInt32(pWnd.Height));
        int largestIntersectingArea = 0;
        System.Windows.Forms.Screen curScreen = null;

        foreach (System.Windows.Forms.Screen s in System.Windows.Forms.Screen.AllScreens)
        {
            if (s.Bounds.IntersectsWith(windowRect))
            {
                intersectingRect = System.Drawing.Rectangle.Intersect(s.Bounds, windowRect);
                int intersectingArea = intersectingRect.Width * intersectingRect.Height;
                if (intersectingArea > largestIntersectingArea)
                {
                    largestIntersectingArea = intersectingArea;
                    curScreen = s;
                }
            }
        }

        return curScreen;
    }
}
4

2 回答 2

3

有一个名为 的 WPF 元素(控件)Thumb,我用它来制作可拖动的部件。它有一个DragDelta事件,您可以使用它来检查可HorizontalOffset拖动VerticalOffset部分。您可以保存以前的值并检查新值是否相同或更改;这意味着它正在被拖动。

(只是一个对我有用的建议)。

于 2013-05-08T23:24:41.717 回答
1

好的,也许有人会觉得这很有帮助。

我改变了一些东西,以便它通过两个事件识别拖动,在 MouseMove 和 MouseLeftButtonDown 事件中。

MouseLeftButtonDown 在 setStartPosition() 中捕获可能的拖动起始位置。

    public void TITLEBAR_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DockPanel dp = (DockPanel)sender;
        Window parentWindow = Window.GetWindow(dp);
        doubleClick = IsDoubleClick(sender, e);

        if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed && !doubleClick)
        {
            if (parentWindow.WindowState == WindowState.Maximized)
            {
                setStartPosition(sender, e);
            }
        }

        if (doubleClick)
        {
            if (parentWindow.WindowState == System.Windows.WindowState.Maximized)
            {
                parentWindow.WindowState = System.Windows.WindowState.Normal;
            }
            else
            {
                parentWindow.WindowState = System.Windows.WindowState.Maximized;
            }
        }
    }

    private void TITLEBAR_MouseMove(object sender, MouseEventArgs e)
    {
        DockPanel dp = (DockPanel)sender;
        Window parentWindow = Window.GetWindow(dp);

        if (e.LeftButton == MouseButtonState.Pressed)
        {
            if (IsDragging(sender, e) && !doubleClick)
            {
                if (parentWindow.WindowState == WindowState.Maximized)
                {
                    double mouseX = e.GetPosition(parentWindow).X;
                    double width = parentWindow.RestoreBounds.Width;
                    System.Drawing.Rectangle screenBounds = getCurrentScreenBounds(parentWindow);
                    double x = screenBounds.Left + (mouseX - ((width / 100.00) * ((100.00 / screenBounds.Width) * mouseX)));

                    if (x < 0)
                    {
                        x = 0;
                    }
                    else
                    {
                        if (x + width > screenBounds.Left + screenBounds.Width)
                        {
                            x = screenBounds.Left + screenBounds.Width - width;
                        }
                    }

                    parentWindow.Left = x;
                    parentWindow.Top = screenBounds.Top;
                    parentWindow.WindowState = System.Windows.WindowState.Normal;
                }

                parentWindow.DragMove();
            }
        }

    }

这是修改后的类:

public static class MouseButtonHelper
{
    private const long k_DoubleClickSpeed = 500;
    private const double k_MaxMoveDistance = 10;

    private static long _LastClickTicks = 0;
    private static System.Windows.Point _LastPosition;
    private static WeakReference _LastSender;

    private static System.Windows.Point _DragStartPosition;

    public static bool IsDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        System.Windows.Point position = e.GetPosition(null);
        long clickTicks = DateTime.Now.Ticks;
        long elapsedTicks = clickTicks - _LastClickTicks;
        long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond;
        bool quickClick = (elapsedTime <= k_DoubleClickSpeed);
        bool senderMatch = (_LastSender != null && sender.Equals(_LastSender.Target));

        if (senderMatch && quickClick && position.Distance(_LastPosition) <= k_MaxMoveDistance)
        {
            // Double click!
            _LastClickTicks = 0;
            _LastSender = null;
            return true;
        }

        // Not a double click
        _LastClickTicks = clickTicks;
        _LastPosition = position;
        if (!quickClick)
            _LastSender = new WeakReference(sender);
        return false;
    }

    public static void setStartPosition(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        _DragStartPosition = e.GetPosition(null);
    }

    public static bool IsDragging(object sender, System.Windows.Input.MouseEventArgs e)
    {
        System.Windows.Point mousePos = e.GetPosition(null);
        System.Windows.Vector diff = _DragStartPosition - mousePos;

        if (Math.Abs(diff.X) > System.Windows.SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > System.Windows.SystemParameters.MinimumVerticalDragDistance)
        {
            return true;
        }
        return false;
    }

    private static double Distance(this System.Windows.Point pointA, System.Windows.Point pointB)
    {
        double x = pointA.X - pointB.X;
        double y = pointA.Y - pointB.Y;
        return Math.Sqrt(x * x + y * y);
    }
}
于 2013-05-10T05:01:36.927 回答