そのため、WPF ウィンドウにはNoResize
、CanMinimize
、CanResize
およびの 4 つのサイズ変更モード オプションしかありませんCanResizeWithGrip
。残念ながら、サイズ変更を有効にするオプションはウィンドウの最大化も有効にしますが、そうでないオプションは私には役に立ちません。
サイズ変更機能を維持したまま、最大化ボタンを無効にするオプションはありますか?
ものを含まないソリューションを好むでしょうWinAPI
。
無効のみ 最大化:
ResizeMode="CanMinimize"
WPF には、WinForms でできるように、最大化ボタンのみを無効にするネイティブ機能がありません。WinAPI 呼び出しに頼る必要があります。怖くない:
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private const int GWL_STYLE = -16;
private const int WS_MAXIMIZEBOX = 0x10000;
private void Window_SourceInitialized(object sender, EventArgs e)
{
var hwnd = new WindowInteropHelper((Window)sender).Handle;
var value = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, (int)(value & ~WS_MAXIMIZEBOX));
}
設定した場合
WindowStyle="ToolWindow"
ウィンドウのプロパティでは、上部に最小化または最大化ボタンのないサイズ変更可能なウィンドウが表示されます。見た目は四角で、閉じるボタンも四角ですが、少なくとも最小化と最大化はありません。
P/Invoke メソッド
マネージド (.NET) コードからアンマネージド コード (この場合は C++) を呼び出す最も簡単な方法は、P/Invoke とも呼ばれるプラットフォーム呼び出しサービスを使用することです。アンマネージ関数の宣言をコンパイラに提供し、他のマネージ メソッドを呼び出すように呼び出すだけです。指定したウィンドウの属性を変更するために使用できるアンマネージ SetWindowLong メソッドがあります。P/Invoke を使用して WPF ウィンドウ クラスからこのメソッドを呼び出せるようにするには、次の宣言をウィンドウ クラスに追加するだけです。
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
DllImport 属性は、メソッドを含む DLL の名前を指定し、 extern キーワードは、C# コンパイラに、メソッドが外部で実装され、アプリケーションのコンパイル時に実装またはメソッド本体が見つからないことを伝えます。SetWindowLong メソッドに渡される最初の引数は、前述のボタンのいずれかを無効にするウィンドウのハンドルです。マネージド WindowInteropHelper クラスのインスタンスを作成し、ウィンドウの SourceInitialized イベントのイベント ハンドラーでその Handle プロパティにアクセスすることで、WPF ウィンドウのハンドルを取得できます。このイベントは、ハンドルが完全に作成されたときに発生します。SetWindowLong メソッドの 2 番目の引数は、設定するウィンドウの属性または値を定数整数値として指定します。ウィンドウのスタイルを変更したいときは、
private const int GWL_STYLE = -16;
最後に、3 番目の引数は置換値を指定します。ここで使用できる一連の定数があります。
private const int WS_MAXIMIZEBOX = 0x10000; //maximize button
private const int WS_MINIMIZEBOX = 0x20000; //minimize button
ただし、2 番目の引数 (この場合はウィンドウ スタイル) で指定された「プロパティ」の完全な値を指定する DWORD を渡す必要があるため、これらの定数を 3 番目の引数として単純に渡すことはできないことに注意してください。メソッドに。特定のプロパティ (この場合は GWL_STYLE) の現在の値を取得する別の GetWindowLong メソッドがあり、ビットごとの演算子を使用して、3 番目のパラメーターの正しい値を取得し、SetWindowLong メソッドに渡すことができます。以下は、たとえば WPF でウィンドウの最小化ボタンを無効にする方法の完全なコード サンプルです。
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private const int GWL_STYLE = -16;
private const int WS_MAXIMIZEBOX = 0x10000; //maximize button
private const int WS_MINIMIZEBOX = 0x20000; //minimize button
public MainWindow() {
InitializeComponent();
this.SourceInitialized += MainWindow_SourceInitialized;
}
private IntPtr _windowHandle;
private void MainWindow_SourceInitialized(object sender, EventArgs e) {
_windowHandle = new WindowInteropHelper(this).Handle;
//disable minimize button
DisableMinimizeButton();
}
protected void DisableMinimizeButton() {
if (_windowHandle == IntPtr.Zero)
throw new InvalidOperationException("The window has not yet been completely initialized");
SetWindowLong(_windowHandle, GWL_STYLE, GetWindowLong(_windowHandle, GWL_STYLE) & ~WS_MAXIMIZEBOX);
}
}
最小化ボタンを無効にするには、WS_MAXIMIZEBOX 定数を WS_MINIMIZEBOX 定数に置き換えるだけです。