2013-04-18 329 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