Q048. Window の最小化・最大化ボタンを無効にするには?
A. SetWindowLong で Window スタイルを設定します。
(2011/07/25 追記)リサイズ不可で最大化だけ無効にしたいなら ResizeMode を CanMinimize に設定するといいです。
関連記事 :Windowの最小化、最大化ボタン
実は私も id:akiramei さんと同じく、ユーザーさんから最大化だけ無効にしたいと要求合ったため Window のプロパティ調べていたら、どこにもないのにマジ愕然・・・。そこで、散々ぐぐって見つけた id:akiramei さんの記事を参考に対処させて頂きました。しかしこれだと Window を継承せねばならぬため、少し美しくないのも事実。そこで添付ビヘイビアに魔改造し、さらに VB の人も使えるよう VB に移植してみました。以下コードです。(でもこの程度のことは標準対応してほしいもんですね)
Option Explicit On Option Strict On Imports System.Runtime.InteropServices Imports System.Windows Imports System.Windows.Interop <Flags()> Public Enum WindowStyleFlag As UInteger WS_SYSMENU = &H80000 WS_MINIMIZEBOX = &H20000 WS_MAXIMIZEBOX = &H10000 End Enum Public Class WindowMenuBehaviors Const GWL_STYLE As Integer = -16 <DllImport("user32")> Private Shared Function GetWindowLong(hWnd As IntPtr, index As Integer) As UInteger End Function <DllImport("user32")> Private Shared Function SetWindowLong(hWnd As IntPtr, index As Integer, dwLong As WindowStyleFlag) As UInteger End Function Public Shared ReadOnly MinimizeBoxProperty As DependencyProperty = DependencyProperty.RegisterAttached("MinimizeBox", GetType(Boolean), GetType(WindowMenuBehaviors), New UIPropertyMetadata(True, AddressOf SourceInitialized)) Public Shared ReadOnly MaximizeBoxProperty As DependencyProperty = DependencyProperty.RegisterAttached("MaximizeBox", GetType(Boolean), GetType(WindowMenuBehaviors), New UIPropertyMetadata(True, AddressOf SourceInitialized)) Public Shared ReadOnly ControlBoxProperty As DependencyProperty = DependencyProperty.RegisterAttached("ControlBox", GetType(Boolean), GetType(WindowMenuBehaviors), New UIPropertyMetadata(True, AddressOf SourceInitialized)) ''' <summary> ''' 最小化ボタン。 ''' </summary> <AttachedPropertyBrowsableForType(GetType(WindowMenuBehaviors))> Public Shared Function GetMinimizeBox(obj As DependencyObject) As Boolean Return CBool(obj.GetValue(MinimizeBoxProperty)) End Function <AttachedPropertyBrowsableForType(GetType(WindowMenuBehaviors))> Public Shared Sub SetMinimizeBox(obj As DependencyObject, value As Boolean) obj.SetValue(MinimizeBoxProperty, value) End Sub ''' <summary> ''' 最大化ボタン。 ''' </summary> <AttachedPropertyBrowsableForType(GetType(WindowMenuBehaviors))> Public Shared Function GetMaximizeBox(obj As DependencyObject) As Boolean Return CBool(obj.GetValue(MaximizeBoxProperty)) End Function <AttachedPropertyBrowsableForType(GetType(WindowMenuBehaviors))> Public Shared Sub SetMaximizeBox(obj As DependencyObject, value As Boolean) obj.SetValue(MaximizeBoxProperty, value) End Sub ''' <summary> ''' システムメニュー。 ''' </summary> <AttachedPropertyBrowsableForType(GetType(WindowMenuBehaviors))> Public Shared Function GetControlBox(obj As DependencyObject) As Boolean Return CBool(obj.GetValue(ControlBoxProperty)) End Function <AttachedPropertyBrowsableForType(GetType(WindowMenuBehaviors))> Public Shared Sub SetControlBox(obj As DependencyObject, value As Boolean) obj.SetValue(ControlBoxProperty, value) End Sub Private Shared Sub SourceInitialized(sender As DependencyObject, e As DependencyPropertyChangedEventArgs) Dim window = TryCast(sender, Window) If (window Is Nothing) Then Return AddHandler window.SourceInitialized, Sub(obj, args) Dim w = TryCast(obj, Window) If (w Is Nothing) Then Return Dim handle As IntPtr = (New WindowInteropHelper(w)).Handle Dim original = CType(GetWindowLong(handle, GWL_STYLE), WindowStyleFlag) Dim current = GetWindowStyle(w, original, e) If (original <> current) Then SetWindowLong(handle, GWL_STYLE, current) End If End Sub End Sub Private Shared Function GetWindowStyle(obj As DependencyObject, windowStyle As WindowStyleFlag, ex As DependencyPropertyChangedEventArgs) As WindowStyleFlag Dim style = windowStyle Select Case ex.Property.Name Case "MinimizeBox" If CBool(obj.GetValue(MinimizeBoxProperty)) Then style = style Or WindowStyleFlag.WS_MINIMIZEBOX Else style = style Xor WindowStyleFlag.WS_MINIMIZEBOX End If Case "MaximizeBox" If CBool(obj.GetValue(MaximizeBoxProperty)) Then style = style Or WindowStyleFlag.WS_MAXIMIZEBOX Else style = style Xor WindowStyleFlag.WS_MAXIMIZEBOX End If Case "ControlBox" If CBool(obj.GetValue(ControlBoxProperty)) Then style = style Or WindowStyleFlag.WS_SYSMENU Else style = style Xor WindowStyleFlag.WS_SYSMENU End If End Select Return style End Function End Class
VB2010 から Sub キーワードもラムダ式使えるようになったので便利です。後はビヘイビアの添付プロパティを使えばおk。
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LivetWPFApplication1" local:WindowMenuBehaviors.MinimizeBox="True" local:WindowMenuBehaviors.MaximizeBox="False" local:WindowMenuBehaviors.ControlBox="False"> <Grid> </Grid> </Window>
WindowMenuBehaviors.ControlBox を False にした場合、コントロールボックスが非表示になります。
最大化ボタンだけ無効にしたければ、WindowMenuBehaviors.MaximizeBox="False" と書くだけでオッケー。下の図だと判りにくいかも知れませんが、最大化ボタンのみ無効になってます。
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LivetWPFApplication1" local:WindowMenuBehaviors.MaximizeBox="False"> <Grid> </Grid> </Window>