2013-04-18 332 views
3

如何禁用最大化雙擊標題上的WPF窗口並保留調整大小可用?禁用最大化雙擊標題上的WPF窗口


我知道ResizeMode禁用最大化,但它也可以防止調整形式

ResizeMode="CanMinimize" 

我知道如何刪除最大化和最小化按鈕,但它仍然可以通過雙擊最大化在標題上。

在WinForms中可以輕鬆實現。剛剛設置FormBorderStyleFixedSingleFixed3D。但它不再是WPF中的選項。


P.S.我正在嘗試一些處理WM_GETMINMAXINFO,WM_SYSCOMMAND等的技巧。但是seems it's not working ...

回答

2

WPF不必禁用最大化窗口(不像的WinForms)一個天然的方式。因此,考慮以下關鍵點:

1.隱藏最大化按鈕

使用WinAPI的是很長的路要走,但只用於隱藏最大化按鈕。使用以下命令:以上仍允許最大化(例如,通過在窗口的標題雙擊)

[DllImport("user32.dll")] 
private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 
[DllImport("user32.dll")] 
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 

private const int GWL_STYLE = -16; 
private const int WS_MAXIMIZEBOX = 0x10000; 

private void Window_SourceInitialized(object sender, EventArgs e) 
{ 
    var hwnd = new WindowInteropHelper((Window)sender).Handle; 
    var value = GetWindowLong(hwnd, GWL_STYLE); 
    SetWindowLong(hwnd, GWL_STYLE, (int)(value & ~WS_MAXIMIZEBOX)); 
} 

2.操作手動最大化

該代碼。

WPF對標題欄行爲沒有控制權。如果您想更改雙擊行爲,則需要刪除標題欄並創建自己的標題欄。看看MahApps.Metro - link to sample是如何完成的。之後,處理雙擊事件。

1

這是否適合您?

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 

    InitializeComponent(); 
    this.SizeChanged += MainWindow_SizeChanged; 
    }  
    void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 

     if (this.WindowState == WindowState.Maximized) 
     { 
     this.WindowState = System.Windows.WindowState.Normal; 
     } 


} 
} 
+0

它不會禁用實際上最大化,並導致閃爍窗口。因此我不能將其標記爲答案。 – 2013-11-25 21:34:04

7

我有一個類似的問題。我的窗口沒有任何窗體邊框或標題欄,但可以移動(使用鼠標)。問題是,如果用戶將窗口移動到屏幕的上邊緣,則Windows會自動最大化該窗口。

我設法通過將以下處理程序附加到窗口的StateChanged事件來解決此問題。

private void OnWindowStateChanged(object sender, EventArgs e) 
{ 
    if (this.WindowState == WindowState.Maximized) 
    { 
     this.WindowState = WindowState.Normal; 
    } 
} 
+2

這是很笨重的,因爲窗口瞬間最大化,然後恢復回來,給出一個醜陋的視覺響應。 – edtheprogrammerguy 2014-11-07 21:23:41

+0

適合Silverlight +1 – Vinnie 2016-08-16 16:39:40

0

另一種簡單的(但醜陋)溶液:

// inside a Window class 
protected override void OnPreviewMouseDoubleClick(MouseButtonEventArgs e) 
{ 
    base.OnPreviewMouseDoubleClick(e); 

    const int titleHeight = 30; 
    var position = e.GetPosition(this); 

    if (position.Y <= titleHeight) 
    { 
     e.Handled = true; 
    } 
} 

注意:使用該標題條上的文本菜單/用戶仍然可以最大化窗口的窗口移動到屏幕的上邊緣。

1

在遇到這個問題和研究這個SO問題後,我決定答案不夠。刪除標題欄後,當雙擊靠近窗口頂部時,窗口仍會最大化。

我選擇了刪除標題欄並禁用雙擊窗口的方法。

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     MouseDoubleClick += (sender, args) => 
     { 
      args.Handled = true; 
     }; 
    } 
} 

在我的應用程序是使用MahApps.Metro這會從MetroWindow,而不是窗口但是上面的例子應該在這兩種情況下工作的繼承。

5

好的解決方案我把MSDN的一些幫助放在一起,用於檢測WPF窗口中的非客戶端鼠標活動。

WndProc中調用handled = true如果msg == WM_NCLBUTTONDBLCLK將阻止窗口在用戶雙擊非客戶區時最大化。

myClass() //c'tor 
{ 
    InitializeComponent(); 
    SourceInitialized += new EventHandler(myClass_SourceInitialized); 
} 

void myClass_SourceInitialized(object sender, EventArgs e) 
{ 
    System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd(new System.Windows.Interop.WindowInteropHelper(this).Handle); 
    source.AddHook(new System.Windows.Interop.HwndSourceHook(WndProc)); 
} 

int WM_NCLBUTTONDBLCLK { get { return 0x00A3; } } 

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    if (msg == WM_NCLBUTTONDBLCLK) 
    { 
     handled = true; //prevent double click from maximizing the window. 
    } 

    return IntPtr.Zero; 
} 

幫助MSDN編號:https://social.msdn.microsoft.com/Forums/vstudio/en-US/f54dde25-b748-4724-a7fe-a355b086cfd4/mouse-event-in-the-nonclient-window-area

+1

@Klaus - 我知道這已經有一段時間了,但這可能會對你有所幫助(未來!)。 – edtheprogrammerguy 2014-11-07 21:38:01