2013-04-14 26 views
8

Tôi có cửa sổ tiêu đề không, vì tôi muốn tạo kiểu cửa sổ của riêng mình.Cách kiểm tra xem cửa sổ có đang bị kéo C# WPF

Tiêu đề và thu nhỏ, tối đa và đóng các nút nằm trong bảng điều khiển dock. Tôi đã thêm trình xử lý sự kiện sau để tối đa hóa, khôi phục và kéo cửa sổ.

Sự cố xảy ra khi cửa sổ được phóng to.

Điều tôi thấy là bất cứ khi nào tôi thực hiện một lần nhấp chuột vào tiêu đề sẽ được khôi phục. Khi tôi chỉ muốn nó khôi phục nếu nó được nhấp đúp hoặc kéo. Tôi có thể thấy lý do tại sao nó đang xảy ra nhưng không chắc chắn làm thế nào để giải quyết điều này.

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

Cùng với lớp này:

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

Và điều này làm việc ra giới hạn của màn hình hiện tại.

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; 
    } 
} 
+6

bạn có thể thêm câu trả lời của bạn sau đó đánh dấu nó sau 2 ngày này sẽ là một cách tốt hơn. bạn có thể nhận được upvotes cho nó :). – Star

+0

Cảm ơn lời khuyên! @Star – Hank

+3

Hank, sao chép cập nhật của bạn vào một câu trả lời và bạn sẽ nhận được một upvote từ tôi cho cả câu hỏi của bạn và câu trả lời của bạn. –

Trả lời

3

Có một yếu tố WPF (điều khiển) có tên Thumb, tôi sử dụng để làm phụ tùng kéo-thể. Nó có sự kiện DragDelta mà bạn có thể sử dụng để kiểm tra HorizontalOffsetVerticalOffset của phần có thể kéo. Bạn có thể lưu các giá trị trước đó và kiểm tra xem các giá trị mới có giống nhau hay không; có nghĩa là nó đang bị kéo.

(Chỉ là đề xuất phù hợp với tôi).

+0

Cảm ơn @ Kaveh, tôi chắc chắn sẽ sử dụng điều này để tinh chỉnh những gì tôi đã làm! – Hank

1

Ok vậy có thể ai đó sẽ thấy điều này hữu ích.

Tôi đã thay đổi mọi thứ xung quanh để nó nhận ra kéo qua hai sự kiện, trong các sự kiện MouseMove và MouseLeftButtonDown.

MouseLeftButtonDown chụp vị trí bắt đầu có thể để kéo trong 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(); 
      } 
     } 

    } 

Đây là lớp chỉnh sửa:

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); 
    } 
} 
Các vấn đề liên quan