2013-04-14 16 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日後にそれをマークします。あなたはそれのためにupvotesを得るかもしれない:)。 – Star

+0

チップをありがとう! @Star – Hank

+3

ハンク、あなたのアップデートを答えにコピーすると、あなたの質問とあなたの答えの両方について私からupvoteを得るでしょう。 –

答えて

3

は、WPF要素(コントロール)という名前Thumbがあり、私が使用して、ドラッグ可能な部品を作るためのもの。これはDragDeltaイベントを持ち、ドラッグ可能な部分のHorizontalOffsetVerticalOffsetを調べることができます。以前の値を保存し、新しい値が同じか変更されているかどうかを確認することができます。それはドラッグされていることを意味します。

(ちょうど私のために働いた提案)。

+0

ありがとう@Kaveh、私は間違いなくこれを使って私が行ったことを洗練するでしょう! – Hank

1

だから、誰かが役に立つと思うかもしれません。

MouseMoveとMouseLeftButtonDownイベントで2つのイベントを介してドラッグを認識するように変更しました。

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); 
    } 
} 
関連する問題