teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

Behavior版を追記しました。

2019/03/20 04:11

投稿

draq
draq

スコア2577

answer CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  下記のサンプルコードは[こちら](https://teratail.com/questions/32055)の回答を WPF 向けに書き換えたものです。
4
4
 
5
+
6
+ (ベヘイビア版を追記しました。)
7
+
8
+ ---
9
+ (コードビハインド版)
5
10
  - MainWindow.xaml
6
11
  ```XAML
7
12
  <Window x:Class="WpfApp1.MainWindow"
@@ -77,4 +82,126 @@
77
82
 
78
83
  }
79
84
  }
85
+ ```
86
+
87
+ ---
88
+ (Behavior版を追記)
89
+ - MainWindow.xaml
90
+ ```XAML
91
+ <Window x:Class="WpfApp1.MainWindow"
92
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
93
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
94
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
95
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
96
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
97
+ xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
98
+ xmlns:local="clr-namespace:WpfApp1"
99
+ mc:Ignorable="d"
100
+ Title="MainWindow"
101
+ Height="450"
102
+ Width="800">
103
+
104
+ <i:Interaction.Behaviors>
105
+ <local:MaximizedWindowBehavior MaximizedBounds="200,500,1920,1080" />
106
+ </i:Interaction.Behaviors>
107
+
108
+ <Grid>
109
+ </Grid>
110
+ </Window>
111
+ ```
112
+
113
+ - MainWindow.xaml.cs
114
+ 既定のまま変更なし
115
+
116
+ - MaximizedWindowBehavior.cs
117
+ ```C#
118
+ using System;
119
+ using System.ComponentModel;
120
+ using System.Runtime.InteropServices;
121
+ using System.Windows;
122
+ using System.Windows.Interactivity;
123
+ using System.Windows.Interop;
124
+
125
+ namespace WpfApp1 {
126
+ class MaximizedWindowBehavior: Behavior<Window> {
127
+
128
+ #region MaximizedBounds Property
129
+
130
+ public Rect MaximizedBounds {
131
+ get => (Rect)this.GetValue( MaximizedBoundsProperty );
132
+ set => this.SetValue( MaximizedBoundsProperty, value );
133
+ }
134
+
135
+ public static readonly DependencyProperty MaximizedBoundsProperty =
136
+ DependencyProperty.Register( nameof( MaximizedBounds ), typeof( Rect ), typeof( MaximizedWindowBehavior ), new PropertyMetadata( Rect.Empty ) );
137
+
138
+ #endregion
139
+
140
+ public MaximizedWindowBehavior() { }
141
+
142
+ protected override void OnAttached() {
143
+ base.OnAttached();
144
+ this.AssociatedObject.Loaded += this.WindowLoaded;
145
+ this.AssociatedObject.Closing += this.WindowClosing;
146
+ }
147
+
148
+ protected override void OnDetaching() {
149
+ this.AssociatedObject.Loaded -= this.WindowLoaded;
150
+ this.AssociatedObject.Closing -= this.WindowClosing;
151
+ base.OnDetaching();
152
+ }
153
+
154
+ private void WindowLoaded( object sender, RoutedEventArgs e ) {
155
+ var hwnd = new WindowInteropHelper( this.AssociatedObject ).Handle;
156
+ var source = HwndSource.FromHwnd( hwnd );
157
+ source.AddHook( this.WndProc );
158
+ }
159
+
160
+ private void WindowClosing( object sender, CancelEventArgs e ) {
161
+ var hwnd = new WindowInteropHelper( this.AssociatedObject ).Handle;
162
+ var source = HwndSource.FromHwnd( hwnd );
163
+ source.RemoveHook( this.WndProc );
164
+ }
165
+
166
+ #region Win32
167
+
168
+ private struct POINT {
169
+ public int x;
170
+ public int y;
171
+ }
172
+
173
+ #pragma warning disable CS0649
174
+ private struct MINMAXINFO {
175
+ public POINT ptReserved;
176
+ public POINT ptMaxSize; // 最大化フォームのサイズ
177
+ public POINT ptMaxPosition; // 最大化フォームの位置
178
+ public POINT ptMinTrackSize; // フォームの最大サイズ
179
+ public POINT ptMaxTrackSize; // フォームの最小サイズ
180
+ }
181
+ #pragma warning restore CS0649
182
+
183
+ private const int WM_GETMINMAXINFO = 0x0024;
184
+
185
+ #endregion
186
+
187
+ private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled ) {
188
+ if( msg == WM_GETMINMAXINFO ) {
189
+ handled = true;
190
+
191
+ var info = Marshal.PtrToStructure<MINMAXINFO>( lParam );
192
+ info.ptMaxPosition.x = (int)this.MaximizedBounds.Left;
193
+ info.ptMaxPosition.y = (int)this.MaximizedBounds.Top;
194
+ if( 0 < this.MaximizedBounds.Width )
195
+ info.ptMaxSize.x = (int)this.MaximizedBounds.Width;
196
+ if( 0 < this.MaximizedBounds.Height )
197
+ info.ptMaxSize.y = (int)this.MaximizedBounds.Height;
198
+ Marshal.StructureToPtr( info, lParam, true );
199
+
200
+ return IntPtr.Zero;
201
+ }
202
+ return IntPtr.Zero;
203
+ }
204
+
205
+ }
206
+ }
80
207
  ```