最近做项目碰到一个需求,要求该窗体禁用最大化按钮,但是保留最小化按钮。窗体大小不可改变。
献贴上效果图
下面是具体做法:
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 ^^
---------------------------------------------------------------------------------------------------------------------