2013-07-31 126 views
1

最大限度地在我的WPF窗口,我已經設置WPF窗口,固定/有限寬度

Width="300" MinWidth="300" MaxWidth="300" 

當我最大化這個窗口,它會靠到這種固定與左屏幕邊框,但對底部窗口是UNDERNEATH的Windows 8任務欄。

我已經試過

public MainWindow() 
{ 
    ... 
    this.MaxHeight = System.Windows.SystemParameters.WorkArea.Height; 
} 

,但這會導致任務欄和我的應用程序之間自由空間幾個像素。

我想會到

  • 有一個固定的寬度窗口
  • 它停靠在右側邊框最大化
  • 沒有覆蓋/走在任務欄下的最大化狀態

回答

5

不幸的是,只需使用MinWidth,MaxWidth和WindowState就可以實現您的三項要求。

但無論如何,仍然有可能實現類似的目標。你需要做的是模擬窗口的最大化狀態。您需要將窗戶移動到正確的位置,找到合適的高度,並使其不能移動。前兩部分很簡單,最後一部分需要一些更高級的東西。

從寬度,最大寬度和最小寬度設置爲300開始,並向StateChanged添加事件處理程序。

Width="300" MinWidth="300" MaxWidth="300" StateChanged="MainWindow_OnStateChanged" 

且事件處理程序,並輔助方法:

private bool isMaximized; 
private Rect normalBounds; 
private void MainWindow_OnStateChanged(object sender, EventArgs e) 
{ 
    if (WindowState == WindowState.Maximized && !isMaximized) 
    { 
     WindowState = WindowState.Normal; 
     isMaximized = true; 

     normalBounds = RestoreBounds; 

     Height = SystemParameters.WorkArea.Height; 
     MaxHeight = Height; 
     MinHeight = Height; 
     Top = 0; 
     Left = SystemParameters.WorkArea.Right - Width; 
     SetMovable(false); 
    } 
    else if(WindowState == WindowState.Maximized && isMaximized) 
    { 
     WindowState = WindowState.Normal; 
     isMaximized = false; 

     MaxHeight = Double.PositiveInfinity; 
     MinHeight = 0; 

     Top = normalBounds.Top; 
     Left = normalBounds.Left; 
     Width = normalBounds.Width; 
     Height = normalBounds.Height; 
     SetMovable(true); 
    } 
} 

private void SetMovable(bool enable) 
{ 
    HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 

    if(enable) 
     source.RemoveHook(WndProc); 
    else 
     source.AddHook(WndProc); 
} 

private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    const int WM_SYSCOMMAND = 0x0112; 
    const int SC_MOVE = 0xF010; 

    switch (msg) 
    { 
     case WM_SYSCOMMAND: 
      int command = wParam.ToInt32() & 0xfff0; 
      if (command == SC_MOVE) 
       handled = true; 
      break; 
    } 

    return IntPtr.Zero; 
}