2012-07-28 29 views
9

Tôi gặp sự cố với cửa sổ tùy chỉnh của mình (AllowTransparency, WindowStyle = None) trong WPF. Phương thức DragMove() hoạt động tốt, nhưng khi tôi phóng to cửa sổ, hoặc nó tối đa hóa tự động bởi Windows 7 Aero Snap, phương pháp này không hoạt động chút nào. Vì vậy, tôi không thể unsnap cửa sổ với kéo chuột và trả lại nó nhà nước để WindowState.Normal. Aero Snap bên trái và bên phải hoạt động tốt, tôi có thể chụp nhanh và bỏ qua cửa sổ mà không gặp vấn đề gì. Nhưng khi nó tối đa, không có gì hoạt động ngoại trừ Win + Down kết hợp. Có lẽ ai đó biết làm thế nào để giải quyết vấn đề này hoặc nơi tôi có thể tìm thấy những cách khác để làm DragMove thích hợp của cửa sổ tùy chỉnh với các tính năng Aero Snap đang hoạt động?DragMove() và Tối đa

Trả lời

12

Đây là phương pháp của tôi. Cố gắng làm cho nó ngắn hơn)))

private void InitHeader() 
{ 
    var border = Find<Border>("borderHeader"); 
    var restoreIfMove = false; 

    border.MouseLeftButtonDown += (s, e) => 
    { 
     if (e.ClickCount == 2) 
     { 
      if ((ResizeMode == ResizeMode.CanResize) || 
       (ResizeMode == ResizeMode.CanResizeWithGrip)) 
      { 
       SwitchState(); 
      } 
     } 
     else 
     { 
      if (WindowState == WindowState.Maximized) 
      { 
       restoreIfMove = true; 
      } 

      DragMove(); 
     } 
    }; 
    border.MouseLeftButtonUp += (s, e) => 
    { 
     restoreIfMove = false; 
    }; 
    border.MouseMove += (s, e) => 
    { 
     if (restoreIfMove) 
     { 
      restoreIfMove = false; 
      var mouseX = e.GetPosition(this).X; 
      var width = RestoreBounds.Width; 
      var x = mouseX - width/2; 

      if (x < 0) 
      { 
       x = 0; 
      } 
      else 
      if (x + width > screenSize.X) 
      { 
       x = screenSize.X - width; 
      } 

      WindowState = WindowState.Normal; 
      Left = x; 
      Top = 0; 
      DragMove(); 
     } 
    }; 
} 

private void SwitchState() 
{ 
    switch (WindowState) 
    { 
     case WindowState.Normal: 
     { 
      WindowState = WindowState.Maximized; 
      break; 
     } 
     case WindowState.Maximized: 
     { 
      WindowState = WindowState.Normal; 
      break; 
     } 
    } 
} 

(Để có được screensize tôi sử dụng phương pháp tự nhiên)

+0

Tuyệt vời! Cảm ơn rất nhiều! –

+0

@groaner bạn có thể trỏ tới màn hìnhSize phương thức gốc bạn đã sử dụng không? – egfconnor

9

giải pháp Groaner của không hoạt động đúng với nhiều thiết lập màn hình, đặc biệt là nơi các màn hình chính không phải là trái nhất.

Đây là giải pháp của tôi dựa trên giải pháp xử lý đơn hoặc nhiều màn hình chính xác. Trong mã này 'rctHeader' là một Hình chữ nhật được xác định trong XAML.

private bool mRestoreIfMove = false; 


    public MainWindow() 
    { 
     InitializeComponent(); 
    } 


    private void SwitchWindowState() 
    { 
     switch (WindowState) 
     { 
      case WindowState.Normal: 
       { 
        WindowState = WindowState.Maximized; 
        break; 
       } 
      case WindowState.Maximized: 
       { 
        WindowState = WindowState.Normal; 
        break; 
       } 
     } 
    } 


    private void rctHeader_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     if (e.ClickCount == 2) 
     { 
      if ((ResizeMode == ResizeMode.CanResize) || (ResizeMode == ResizeMode.CanResizeWithGrip)) 
      { 
       SwitchWindowState(); 
      } 

      return; 
     } 

     else if (WindowState == WindowState.Maximized) 
     { 
      mRestoreIfMove = true; 
      return; 
     } 

     DragMove(); 
    } 


    private void rctHeader_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     mRestoreIfMove = false; 
    } 


    private void rctHeader_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (mRestoreIfMove) 
     { 
      mRestoreIfMove = false; 

      double percentHorizontal = e.GetPosition(this).X/ActualWidth; 
      double targetHorizontal = RestoreBounds.Width * percentHorizontal; 

      double percentVertical = e.GetPosition(this).Y/ActualHeight; 
      double targetVertical = RestoreBounds.Height * percentVertical; 

      WindowState = WindowState.Normal; 

      POINT lMousePosition; 
      GetCursorPos(out lMousePosition); 

      Left = lMousePosition.X - targetHorizontal; 
      Top = lMousePosition.Y - targetVertical; 

      DragMove(); 
     } 
    } 



    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool GetCursorPos(out POINT lpPoint); 


    [StructLayout(LayoutKind.Sequential)] 
    public struct POINT 
    { 
     public int X; 
     public int Y; 

     public POINT(int x, int y) 
     { 
      this.X = x; 
      this.Y = y; 
     } 
    } 


} 
4

Trong WPF tôi rất muốn khuyên bạn sử dụng Control.PointToScreen khi khôi phục các cửa sổ trước khi Window.DragMove của bạn. PointToScreen cũng sẽ xử lý nhiều thiết lập màn hình. Điều này sẽ đơn giản hóa việc khôi phục về những điều sau:

private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     if(e.ClickCount == 2) 
     { 
      if(ResizeMode != ResizeMode.CanResize && 
       ResizeMode != ResizeMode.CanResizeWithGrip) 
      { 
       return; 
      } 

      WindowState = WindowState == WindowState.Maximized 
       ? WindowState.Normal 
       : WindowState.Maximized; 
     } 
     else 
     { 
      mRestoreForDragMove = WindowState == WindowState.Maximized; 
      DragMove(); 
     } 
    } 

    private void OnMouseMove(object sender, MouseEventArgs e) 
    { 
     if(mRestoreForDragMove) 
     { 
      mRestoreForDragMove = false; 

      var point = PointToScreen(e.MouseDevice.GetPosition(this)); 

      Left = point.X - (RestoreBounds.Width * 0.5); 
      Top = point.Y; 

      WindowState = WindowState.Normal; 

      DragMove(); 
     } 
    } 

    private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     mRestoreForDragMove = false; 
    } 

    private bool mRestoreForDragMove; 
+0

Giải pháp này hoạt động hoàn hảo, chính xác những gì tôi đang tìm kiếm. Cảm ơn bạn đã chia sẻ. – Al0x

+0

So với các giải pháp khác, điều này là làm việc tốt nhất - nó có sai sót nhỏ của nó nhưng nó hoạt động thực sự tốt dù sao. –

2

Một chút trễ cho câu trả lời khác, nhưng mã của tôi đơn giản hơn vì vậy tôi sẽ đặt nó ở đây. Như bạn, người đàn ông bên trái và bên phải chụp hoạt động tốt nhưng khi cửa sổ được phóng to hoặc bẻ cong đến giới hạn trên màn hình và tối đa hóa, phương pháp DragMove sẽ không hoạt động!


Chỉ cần xử lý các tổ chức sự kiện Mouse_Down trên các yếu tố bạn muốn kéo với như thế này:

private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    if (WindowState == WindowState.Maximized) 
    { 
     var point = PointToScreen(e.MouseDevice.GetPosition(this)); 

     if (point.X <= RestoreBounds.Width/2) 
      Left = 0; 

     else if (point.X >= RestoreBounds.Width) 
      Left = point.X - (RestoreBounds.Width - (this.ActualWidth - point.X)); 

     else 
      Left = point.X - (RestoreBounds.Width/2); 

     Top = point.Y - (((FrameworkElement)sender).ActualHeight/2); 
     WindowState = WindowState.Normal; 
    } 
    DragMove(); 
} 

Tôi hy vọng nó sẽ giúp người!

+0

Thỉnh thoảng nó xảy ra khi cửa sổ trở lại trạng thái bình thường nhưng không bám vào chuột gây khó chịu. –

Các vấn đề liên quan