2013-04-14 6 views
8

У меня есть окно без заголовка, так как я хотел создать собственный стиль окна.Как проверить, перетаскивается ли окно C# WPF

Названия и кнопки минимизации, максимизации и закрытия находятся в панели док-станции. Я добавил следующий обработчик событий, чтобы максимизировать, восстановить и перетащить окно.

Проблема возникает, когда окно максимально.

Я обнаружил, что всякий раз, когда я нажимаю на заголовок, восстанавливается. Когда я только хочу, чтобы он был восстановлен, если его дважды щелкнуть или перетащить. Я могу понять, почему это происходит, но не знаете, как это решить.

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

вы можете добавить свой ответ, то отметьте его через 2 дня, это будет лучше. вы можете получить его за это :). – Star

+0

Спасибо за подсказку! @Star – Hank

+3

Хэнк, скопируйте свое обновление в ответ, и вы получите от меня ответ, как на свой вопрос, так и на свой ответ. –

ответ

3

Существует WPF элемент (управления) с именем Thumb, я использую это для создания сопротивления-состояния частей. У этого есть событие DragDelta, которое вы можете использовать, чтобы осмотреть HorizontalOffset и VerticalOffset детали, которые можно перетащить. Вы можете сохранить предыдущие значения и проверить, являются ли новые значения одинаковыми или изменены; что означает, что его таскают.

(Просто предложение, которое сработало для меня).

+0

Спасибо @Kaveh, я определенно буду использовать это, чтобы уточнить, что я сделал! – Hank

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); 
    } 
} 
Смежные вопросы