ligaibing 发表于 2013-2-7 03:49:13

Disable Minimize and Maximize Buttons Through Attached Properties From XAML

Overview
Yesterday I worked up a static helper class that encapsulates the functionality to disable/enable/toggle the minimize and maximize buttons on a standard WPF window. This morning I updated that code to fix some bugs that I overlooked. Finally just not long ago, I updated the code with a new static class called WindowCustomizer, which allows this same functionality through the use of attached properties straight from XAML-markup. The advantage here is that this is now a full MVVM-compliant solution.

WindowCustomizer.cs
This file contains the static class WindowCustomizer which enables the use of attached properties, and delegates its work to it’s nested static class WindowHelper which was seen in my previous post. On a low-level the bulk of the work is done by making calls to the Win32 API. I have chosen to use 32/64-bit compatible functions to allow for the most compatible solution. In addition I have surround the low-level code that modifies the WPF window with lock statements just as a precaution, although I don’t expect any problems either way.
using System;using System.Runtime.InteropServices;using System.Windows;using System.Windows.Interop;namespace WindowCustomizerExample{    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      #region WindowHelper Nested Class      public static class WindowHelper      {            private const Int32 GWL_STYLE = -16;            private const Int32 WS_MAXIMIZEBOX = 0x00010000;            private const Int32 WS_MINIMIZEBOX = 0x00020000;                        private extern static Int32 GetWindowLongPtr(IntPtr hWnd, Int32 nIndex);                        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);                  }                }            }      }      #endregion WindowHelper Nested Class    }} Example Usage (Window1.xaml)
Using the WindowCustomizer is extremely straightforward, provides minimal clutter, and allows for a fully MVVM-compliant solution. The XAML-markup below will disable both the minimize and maximize functionality from the WPF window, and in turn disable their associated system menu menuitems as well. Be aware the only way to completely remove both buttons from the WPF window’s titlebar (as opposed to just disabling them) is to set both CanMaximize and CanMinimize to False; In this example both buttons will therefore be completely removed.
<Window x:Class="WindowCustomizerExample.Window1"      Title="Window1"      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      xmlns:local="clr-namespace:WindowCustomizerExample"      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"      local:WindowCustomizer.CanMaximize="False"      local:WindowCustomizer.CanMinimize="False"></Window> From:http://thrash505.wordpress.com/2010/04/19/wpf-window-disable-minimize-and-maximize-buttons-through-attached-properties-from-xaml/
 
页: [1]
查看完整版本: Disable Minimize and Maximize Buttons Through Attached Properties From XAML