如何从WPF中可调整大小的窗口中删除最小化和最大化?


80

WPF不提供具有允许调整大小但没有最大化或最小化按钮的窗口的功能。我希望能够制作一个这样的窗口,以便可以调整对话框的大小。

我知道该解决方案将意味着使用pinvoke,但我不确定该如何呼叫。搜索pinvoke.net并没有发现我需要的任何东西,主要是我确定,因为Windows窗体确实在其窗口中提供CanMinimizeCanMaximize属性。

有人可以指向我或提供有关如何执行此操作的代码(首选C#)吗?

Answers:


113

我偷了一些在MSDN论坛上找到的代码,并在Window类上做了一个扩展方法,如下所示:

internal static class WindowExtensions
{
    // from winuser.h
    private const int GWL_STYLE      = -16,
                      WS_MAXIMIZEBOX = 0x10000,
                      WS_MINIMIZEBOX = 0x20000;

    [DllImport("user32.dll")]
    extern private static int GetWindowLong(IntPtr hwnd, int index);

    [DllImport("user32.dll")]
    extern private static int SetWindowLong(IntPtr hwnd, int index, int value);

    internal static void HideMinimizeAndMaximizeButtons(this Window window)
    {
        IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
        var currentStyle = GetWindowLong(hwnd, GWL_STYLE);

        SetWindowLong(hwnd, GWL_STYLE, (currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX));
    }
}

要记住的唯一另一件事是,由于某种原因,这在窗口的构造函数中不起作用。我通过将其添加到构造函数中来解决了这个问题:

this.SourceInitialized += (x, y) =>
{
    this.HideMinimizeAndMaximizeButtons();
};

希望这可以帮助!


3
窗口中一些更漂亮的代码:受保护的重写void OnSourceInitialized(EventArgs e){base.OnSourceInitialized(e); this.HideMinimizeAndMaximizeButtons(); }
Dmitry Shechtman

1
为什么不简化它并直接在HideMinimizeAndMaximizeButtons()方法中订阅SourceInitialized事件?然后,您可以从构造函数中调用该方法,而不必执行其他任何操作。
jmatthias

1
此解决方案不包括双击标题栏。
Lonli-Lokli 2011年

1
复活注意!该方法必须放入Windows Loaded事件中,因为该句柄未在Initialized事件中定义。
SezMe

4
在所有这些时间都知道Windows窗体中存在此功能之后,我只是不了解microsoft从一开始就没有在WPF中放置这种功能。坦率地说,带有最小化框和最大化书的对话框看起来不专业,并且标题栏的双击也是同样的问题。抱歉让我对WPF感到沮丧,它非常好,并且具有字符串资产,但是偶尔您偶然发现一些本来应该简单但最终不是的简单东西。
菲利普·斯图克

91

一种方法是设置您的帐户ResizeMode="NoResize"。它将像这样。 在此处输入图片说明

我希望这有帮助!


32
这将使窗口无法调整大小,这与问题直接相反。
Mashmagar

5
通常,正在寻找禁用最小化和最大化按钮的方式的Google员工对窗口的大小调整没有特殊要求。当前,这是“ wpf窗口禁用最小化”查询的最佳结果,并且此答案正确回答了该问题。无论如何,可惜的是,MS没有将标题栏或整个窗口的镶边设为“仅仅是另一个控件或属性”。'90年代
以来

2
在这种情况下,具有动态宽度的元素(例如DockPanel)仍然能够更改窗口大小。但不再是用户。因此,该选项实际上满足了我的要求。
OneWorld 2013年

3
不回答问题,但对我有所帮助。谢谢。
dkantowitz

@EmperorOrionii可能在此页面上一直是Google的最佳搜索结果,但绝不意味着当您认为它没有解决“如何从resizable windowWPF中删除最小化和最大化?”时,此答案是最佳的删除“调整大小”从最终产品方面。这就像在帮助想要将其汽车涂成红色的人,并在此过程中卸下引擎。
MickyD

22

不知道这是否适合您的要求。视觉上..这是

<Window x:Class="DataBinding.MyWindow" ...Title="MyWindow" Height="300" Width="300" 
    WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip">

3
这几乎可行,但是如果双击标题栏,右键单击并使用控制菜单或任务栏按钮(如果可用),仍然可以最大化或最小化窗口。加上它当然看起来像一个工具窗口,而不是普通的窗口。
Nidonocu

是的...但是再次恕我直言,约束似乎很奇怪,不允许用户最大化,但可以通过调整大小来手动拖动窗口。但这是您的窗口..您的规则:)
Gishu

这对于已设置MaxWidth和和或MaxHeight窗口的情况很方便。
布雷特·瑞安

6

如果有人使用Devexpress窗口(DXWindow),则接受的答案将不起作用。一种丑陋的方法是

public partial class MyAwesomeWindow : DXWindow
{
    public MyAwesomeWIndow()
    {
       Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        // hides maximize button            
        Button button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_Maximize.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;

        // hides minimize button
        button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_Minimize.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;

        // hides close button
        button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_CloseButton.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;
    } 
}

在我注意到您的答案之前,我可能阅读了五篇不同的文章。这确实有效,但是。您找到更好的方法了吗?
DonBoitnott

3

这是我正在使用的解决方案。请注意,最大化按钮仍然显示。

标记:

<Window x:Class="Example"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Example"
        StateChanged="Window_StateChanged">

后面的代码:

// Disable maximizing this window
private void Window_StateChanged(object sender, EventArgs e)
{
    if (this.WindowState == WindowState.Maximized)
        this.WindowState = WindowState.Normal;
}

1
他问如何隐藏按钮但保留功能。
亚历山德鲁·迪库

最小化,窗口闪烁。不太好
Mugen 2015年

2

如果要删除“最小化和最大化”按钮,可以设置窗口的ResizeMode =“ NoResize”


恩,但是您不能调整大小,应该可以
Karsten

0

@MattHamilton提出解决方案的这种变体可以(并且必须)在Window的构造函数中调用。技巧是SourceInitialized在扩展方法中为事件订阅委托。

private const int GWL_STYLE = -16, WS_MAXIMIZEBOX = 0x10000, WS_MINIMIZEBOX = 0x20000;

[DllImport("user32.dll")]
extern private static int GetWindowLong(IntPtr hwnd, int index);

[DllImport("user32.dll")]
extern private static int SetWindowLong(IntPtr hwnd, int index, int value);

/// <summary>
/// Hides the Minimize and Maximize buttons in a Window. Must be called in the constructor.
/// </summary>
/// <param name="window">The Window whose Minimize/Maximize buttons will be hidden.</param>
public static void HideMinimizeAndMaximizeButtons(this Window window)
{
    window.SourceInitialized += (s, e) => {
        IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
        int currentStyle = GetWindowLong(hwnd, GWL_STYLE);

        SetWindowLong(hwnd, GWL_STYLE, currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
    };
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.