[WPF]自由配置窗体最大化、最小化按钮是否可用,窗口大小不可改变

最近做项目碰到一个需求,要求该窗体禁用最大化按钮,但是保留最小化按钮。窗体大小不可改变。

献贴上效果图

下面是具体做法:

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 ^^

 

 

---------------------------------------------------------------------------------------------------------------------

参考:http://thrash505.wordpress.com/2010/04/19/wpf-window-disable-minimize-and-maximize-buttons-through-attached-properties-from-xaml

posted @ 2011-01-24 17:06  Ahriman  阅读(9601)  评论(11编辑  收藏  举报