禁用WPF窗口的最大化按钮,保持调整大小功能完好无损

Pet*_* W. 42 .net c# wpf

因此,WPF窗口只有四天调整模式选项:NoResize,CanMinimize,CanResizeCanResizeWithGrip.不幸的是,启用调整大小的选项也可以使窗口最大化,而那些不起作用的窗口对我来说毫无用处.

是否有选项可以在保持调整大小功能的同时禁用最大化按钮?

我更喜欢不涉及WinAPI东西的解决方案.

557*_*352 71

仅禁用最大化:

ResizeMode="CanMinimize"
Run Code Online (Sandbox Code Playgroud)

  • 这也会禁用调整窗口大小 (14认同)
  • @RobSiklos谢谢,我试图做两个哈哈,即将调查如何禁用调整大小并看到你的评论. (2认同)

Sco*_*ott 30

WPF没有单独禁用"最大化"按钮的本机功能,就像使用WinForms一样.您需要使用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));
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上,我错了.对不起,应该进行更彻底的测试.根据您的问题,此代码将隐藏最大化按钮.如果设置MaxWidth/MaxHeight,则最大化窗口只会将其移动到左上角.内容不会超过您设置的最大大小. (3认同)

Tra*_*mot 28

如果你设置

WindowStyle="ToolWindow"
Run Code Online (Sandbox Code Playgroud)

在窗口的属性中,它将为您提供一个可调整大小的窗口,顶部没有最小化或最大化按钮.它将是方形的,关闭按钮也是正方形,但至少最小化和最大化不存在!

  • 但这可以通过双击窗口来绕过 (6认同)

Sha*_*nda 9

P/Invoke方法

从托管(.NET)代码调用非托管代码(在本例中为C++)的最简单方法是使用平台调用服务,通常也称为P/Invoke.您只需向编译器提供非托管函数的声明,并像调用任何其他托管方法一样调用它.有一个非托管的SetWindowLong方法,可用于更改指定窗口的属性.为了能够使用P/Invoke从WPF窗口类调用此方法,只需将以下声明添加到窗口类:

[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
Run Code Online (Sandbox Code Playgroud)

DllImport属性指定包含该方法的DLL的名称,extern关键字告诉C#编译器该方法是在外部实现的,并且在编译应用程序时它不会找到它的任何实现或方法体.要传递给SetWindowLong方法的第一个参数是要禁用任何提到的按钮的窗口的句柄.您可以通过创建托管的WindowInteropHelper类的实例来获取WPF窗口的句柄,并在窗口的SourceInitialized事件的事件处理程序中访问其Handle属性.完全创建句柄后会引发此事件.SetWindowLong方法的第二个参数指定要设置的窗口的属性或值,表示为常量整数值.如果要更改窗口样式,则应将GWL_STYLE(= - 16)常量作为方法的第二个参数传递.

private const int GWL_STYLE = -16;
Run Code Online (Sandbox Code Playgroud)

最后,第三个参数指定替换值.您可以在此处使用一组常量:

private const int WS_MAXIMIZEBOX = 0x10000; //maximize button
private const int WS_MINIMIZEBOX = 0x20000; //minimize button
Run Code Online (Sandbox Code Playgroud)

但请注意,由于您应该传入一个DWORD来指定第二个参数指定的"property"的完整值,即本例中的窗口样式,您不能简单地将这些常量中的任何一个作为第三个参数传递给它们方法.还有另一个GetWindowLong方法可以检索特定属性的当前值 - 在本例中也是GWL_STYLE - 然后您可以使用按位运算符来获取要传递给SetWindowLong方法的第三个参数的正确值.下面是一个完整的代码示例,说明如何禁用WPF中窗口的最小化按钮:

public partial class MainWindow : Window
{
 [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; //maximize button
 private const int WS_MINIMIZEBOX = 0x20000; //minimize button

 public MainWindow() {
  InitializeComponent();
  this.SourceInitialized += MainWindow_SourceInitialized;
}

private IntPtr _windowHandle;
private void MainWindow_SourceInitialized(object sender, EventArgs e) {
_windowHandle = new WindowInteropHelper(this).Handle;

 //disable minimize button
 DisableMinimizeButton();
}

protected void DisableMinimizeButton() {
  if (_windowHandle == IntPtr.Zero)
    throw new InvalidOperationException("The window has not yet been completely initialized");

   SetWindowLong(_windowHandle, GWL_STYLE, GetWindowLong(_windowHandle,  GWL_STYLE) & ~WS_MAXIMIZEBOX);
 }
}
Run Code Online (Sandbox Code Playgroud)

禁用最小化按钮只需要用WS_MINIMIZEBOX替换WS_MAXIMIZEBOX常量


byt*_*e77 6

另一种选择是捕获StateChanged窗口最大化时引发的事件。然后只需将其设置WindowState为“正常”。

然而,这并没有隐藏最大化框!

private void Window_StateChanged(object sender, EventArgs e)
{
    if (WindowState == WindowState.Maximized)
    {
        WindowState = WindowState.Normal;
    }
}
Run Code Online (Sandbox Code Playgroud)