【问题标题】:How to remove minimize and maximize buttons from a resizable window?如何从可调整大小的窗口中删除最小化和最大化按钮?
【发布时间】:2010-09-25 06:34:30
【问题描述】:

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

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

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

【问题讨论】:

    标签: wpf user-interface resize pinvoke


    【解决方案1】:

    @MattHamilton 的 solution proposed 的这个变体可以(并且必须)在 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);
        };
    }
    

    【讨论】:

      【解决方案2】:

      如果有人使用 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;
          } 
      }
      

      【讨论】:

      • 在我注意到您的回答之前,我可能阅读了五篇不同的帖子。这确实有效,但是很糟糕。你有没有找到更好的方法?
      【解决方案3】:

      一种方法是设置您的ResizeMode="NoResize"。它会表现得像这样。

      我希望这会有所帮助!

      【讨论】:

      • 这会使窗口无法调整大小,这与问题直接相反。
      • 一般来说,寻找禁用最小化和最大化按钮的方法的谷歌用户没有特定的要求来调整窗口大小。目前这是“wpf 窗口禁用最小化”查询的最佳结果,这个答案正确回答了这个问题。无论如何,遗憾的是 MS 没有将标题栏或整个窗口镶边设置为“只是另一个控件或属性”。 90 年代的遗产太多了……
      • 在这种情况下,具有动态宽度的元素(例如 DockPanel)仍然能够更改窗口大小。但不再是用户。所以,这个选项实际上满足了我的要求。
      • 不回答问题,但对我有帮助。谢谢。
      • @EmperorOrionii 虽然当时此页面可能是 Google 的最高搜索结果,但绝不意味着当您认为此答案未解决 “我如何删除从 WPF 中的 resizable window 最小化和最大化?” 当它从成品中删除 “可调整大小” 方面。这就像帮助一个想把汽车漆成红色的人,在这个过程中你拆掉了引擎。
      【解决方案4】:

      我偷了一些在 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();
      };
      

      希望这会有所帮助!

      【讨论】:

      • Window 中更漂亮的代码:protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); this.HideMinimizeAndMaximizeButtons(); }
      • 为什么不让它更简单,并在 HideMinimizeAndMaximizeButtons() 方法中订阅 SourceInitialized 事件?然后你可以从构造函数中调用该方法,而无需其他任何东西。
      • 此解决方案不包括双击标题栏。
      • @Lonli-Lokli 实际上,确实如此。当使用 Win32 API 隐藏按钮时,它还会禁用窗口上下文菜单选项和双击标题。
      • 在知道这个功能存在于 Windows 窗体中这么久之后,我只是不明白微软从一开始就没有把这种功能放在 WPF 中。坦率地说,带有最小化框和最大化书的对话框看起来很不专业,双击标题栏也是同样的问题。抱歉,有点让我对 WPF 感到沮丧,它非常好,并且有字符串资产,但有时你会偶然发现一些应该很简单但最终却不是的东西。
      【解决方案5】:

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

      标记:

      <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;
      }
      

      【讨论】:

      • 他问如何隐藏按钮但保留功能。
      • 尽管如此,窗口却在闪烁。不太好。
      【解决方案6】:

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

      【讨论】:

      • 嗯,但是你不能调整它应该可以
      【解决方案7】:

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

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

      【讨论】:

      • 这几乎可以工作,但是如果您双击标题栏,右键单击并使用控制菜单或任务栏按钮(如果可用),它仍然可以最大化或最小化窗口。当然,它看起来像一个工具窗口,而不是普通的。
      • 对...但是恕我直言,约束似乎很奇怪,不允许用户最大化但可以通过调整大小手动拖动放大窗口。但这是你的窗口..你的规则:)
      • 这对于设置了窗口的MaxWidth 和/或MaxHeight 的情况很方便。
      猜你喜欢
      • 2011-05-14
      • 1970-01-01
      • 2015-05-02
      • 2011-02-09
      • 2016-04-20
      • 2012-12-16
      • 1970-01-01
      • 2014-11-25
      • 2011-04-26
      相关资源
      最近更新 更多