最近做项目碰到一个需求,要求该窗体禁用最大化按钮,但是保留最小化按钮。窗体大小不可改变。
献贴上效果图
下面是具体做法:
1. 自定义了两个DependencyProperty,具体实现需要用到User32.dll中的函数。代码如下:
public static class WindowCustomizer { #region CanMaximize public static readonly DependencyProperty CanMaximize = DependencyProperty.RegisterAttached("CanMaximize", typeof(bool), typeof(Window), new PropertyMetadata(true, new PropertyChangedCallback(OnCanMaximizeChanged))); private static void OnCanMaximizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Window window = d as Window; if (window != null) { RoutedEventHandler loadedHandler = null; loadedHandler = delegate { if ((bool)e.NewValue) { WindowHelper.EnableMaximize(window); } else { WindowHelper.DisableMaximize(window); } window.Loaded -= loadedHandler; }; if (!window.IsLoaded) { window.Loaded += loadedHandler; } else { loadedHandler(null, null); } } } public static void SetCanMaximize(DependencyObject d, bool value) { d.SetValue(CanMaximize, value); } public static bool GetCanMaximize(DependencyObject d) { return (bool)d.GetValue(CanMaximize); } #endregion CanMaximize #region CanMinimize public static readonly DependencyProperty CanMinimize = DependencyProperty.RegisterAttached("CanMinimize", typeof(bool), typeof(Window), new PropertyMetadata(true, new PropertyChangedCallback(OnCanMinimizeChanged))); private static void OnCanMinimizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Window window = d as Window; if (window != null) { RoutedEventHandler loadedHandler = null; loadedHandler = delegate { if ((bool)e.NewValue) { WindowHelper.EnableMinimize(window); } else { WindowHelper.DisableMinimize(window); } window.Loaded -= loadedHandler; }; if (!window.IsLoaded) { window.Loaded += loadedHandler; } else { loadedHandler(null, null); } } } public static void SetCanMinimize(DependencyObject d, bool value) { d.SetValue(CanMinimize, value); } public static bool GetCanMinimize(DependencyObject d) { return (bool)d.GetValue(CanMinimize); } #endregion CanMinimize }
public static class WindowHelper { private const Int32 GWL_STYLE = -16; private const Int32 WS_MAXIMIZEBOX = 0x00010000; private const Int32 WS_MINIMIZEBOX = 0x00020000; [DllImport("User32.dll", EntryPoint = "GetWindowLong")] private extern static Int32 GetWindowLongPtr(IntPtr hWnd, Int32 nIndex); [DllImport("User32.dll", EntryPoint = "SetWindowLong")] private extern static Int32 SetWindowLongPtr(IntPtr hWnd, Int32 nIndex, Int32 dwNewLong); /// <summary> /// Disables the maximize functionality of a WPF window. /// </summary> /// <param name="window">The WPF window to be modified.</param> public static void DisableMaximize(Window window) { lock (window) { IntPtr hWnd = new WindowInteropHelper(window).Handle; Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE); SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MAXIMIZEBOX); } } /// <summary> /// Disables the minimize functionality of a WPF window. /// </summary> /// <param name="window">The WPF window to be modified.</param> public static void DisableMinimize(Window window) { lock (window) { IntPtr hWnd = new WindowInteropHelper(window).Handle; Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE); SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MINIMIZEBOX); } } /// <summary> /// Enables the maximize functionality of a WPF window. /// </summary> /// <param name="window">The WPF window to be modified.</param> public static void EnableMaximize(Window window) { lock (window) { IntPtr hWnd = new WindowInteropHelper(window).Handle; Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE); SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MAXIMIZEBOX); } } /// <summary> /// Enables the minimize functionality of a WPF window. /// </summary> /// <param name="window">The WPF window to be modified.</param> public static void EnableMinimize(Window window) { lock (window) { IntPtr hWnd = new WindowInteropHelper(window).Handle; Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE); SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MINIMIZEBOX); } } /// <summary> /// Toggles the enabled state of a WPF window's maximize functionality. /// </summary> /// <param name="window">The WPF window to be modified.</param> public static void ToggleMaximize(Window window) { lock (window) { IntPtr hWnd = new WindowInteropHelper(window).Handle; Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE); if ((windowStyle | WS_MAXIMIZEBOX) == windowStyle) { SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MAXIMIZEBOX); } else { SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MAXIMIZEBOX); } } } /// <summary> /// Toggles the enabled state of a WPF window's minimize functionality. /// </summary> /// <param name="window">The WPF window to be modified.</param> public static void ToggleMinimize(Window window) { lock (window) { IntPtr hWnd = new WindowInteropHelper(window).Handle; Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE); if ((windowStyle | WS_MINIMIZEBOX) == windowStyle) { SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MINIMIZEBOX); } else { SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MINIMIZEBOX); } } } }
2. 在窗体中使用这两个Property,就可以自由enable/disable最大化和最小化按钮了。需要注意,ResizeMode需设置为CanResize,否则最大化和最小化按钮都会隐藏。
<Window x:Class="TestlogAnalysis.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestlogAnalysis" local:WindowCustomizer.CanMaximize="False" ResizeMode="CanResize" Title="Testlog Analysis" Height="322" Width="397" DataContext="{Binding}" Loaded="Window_Loaded">
3. 禁止Resize,实际上只是把窗口的MinSize和MaxSize设置成一样即可。
private void Window_Loaded(object sender, RoutedEventArgs e) { this.MaxHeight = this.Height; this.MinHeight = this.Height; this.MaxWidth = this.Width; this.MinWidth = this.Width; }
使用如上方法,基本可以满足各种对窗体大小的需求了。FYI ^^
---------------------------------------------------------------------------------------------------------------------