如何实现WPF窗口最大化,且不可调整大小/移动?

14

我想制作一个WPF窗口,它在打开时已经最大化了,无法调整大小/移动(在系统菜单或边框中都不能)。除了用户将其最小化之外,它应该一直最大化。

我尝试使用WindowState="Maximized"和ResizeMode="CanMinimize",但是当窗口打开时,它会覆盖任务栏(我不希望这样)。

我有一个钩子来取消SC_MOVE和SC_SIZE的WndProc。我也可以通过WndProc中的条件控制来实现此功能,例如“如果命令是恢复且已最小化,则还原,否则阻止”等等。

但我的重点是是否有另一种方法来实现这一点。

谢谢大家阅读 =)


这是所有Windows应用程序框架中都存在的常见问题。应用程序框架非常好,它们使我们能够快速编写应用程序。问题在于它们无法涵盖每种可能的情况,并且因为它们的目的是隐藏底层系统的细节,当我们发现需要具有非标准行为时,我们必须深入挖掘并编写“丑陋”的代码。 - Tergiver
你想要一个窗口,它只能最大化或最小化,没有普通状态可以调整大小/移动?但又不是全屏幕吗? - John Gardner
@John Gardner,这正是我想要的。 - Thieres Tembra
4个回答

26

在您的窗口的xaml中需要写入 WindowState="Maximized" ResizeMode="NoResize":

<Window x:Class="Miscellaneous.EditForm"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Edit Form" WindowState="Maximized" ResizeMode="NoResize"></Window>

将 WindowState="Maximized" 设置与 SplashScreen 功能不兼容(主窗口将隐藏闪屏)。如果您不以最大化方式启动,则 ResizeMode="NoResize" 将防止窗口最大化。 - Rob Campbell

3
    public Window1()
    {
         InitializeComponent();

          this.SourceInitialized += Window1_SourceInitialized;
    }

    private void Window1_SourceInitialized(object sender, EventArgs e)
    {
        WindowInteropHelper helper = new WindowInteropHelper(this);
        HwndSource source = HwndSource.FromHwnd(helper.Handle);
        source.AddHook(WndProc);
    }

    const int WM_SYSCOMMAND = 0x0112;
    const int SC_MOVE = 0xF010;

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {

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

2
这段代码将防止窗口被移动或最大化。如果您改用SC_SIZE,则允许窗口最大化和最小化,但无法调整大小。const int SC_SIZE = 0xF000; 在我的窗口xaml中,我使用WindowState="Minimized"和ResizeMode="CanResize"。 - Rob Campbell

3
WindowState="Maximized"
ResizeMode="NoResize"
WindowStyle="None"

WindowStyle="None"可以实现你想要的效果,但是会失去窗口标题、关闭按钮以及出现其他问题。

参考WindowStyle="None" some problems


1
正如Tergiver所指出的那样,这在纯WPF方式下是不可能实现的。您必须使用P/Invoke。至于为什么窗口在打开时覆盖了任务栏,我认为您取消了SC_MOVE和SC_SIZE的一些必要调用,可能应该在窗口加载后再取消这些调用。

PInvoke是什么?在窗口构造函数中怎么样?// 防止窗口重叠任务栏 this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight; this.MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth; - Califf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接