回答編集履歴

1

見直しキャンペーン中

2023/07/28 16:41

投稿

TN8001
TN8001

スコア9341

test CHANGED
@@ -1,359 +1,180 @@
1
1
  `GridLength`を文字列でバインドすると、`Star`・`Pixcel`両対応でいい感じでした。
2
2
 
3
-
4
-
5
3
  再利用性のないユーザーコントロールに、`DependencyProperty`を生やすのは趣味でないのでベタ書きです(生やすなら汎用的に作りたいという意味です)
6
-
7
4
  ユーザーコントロールにするなら文字列(か`GridLength`)を中継する`DependencyProperty`を生やすだけです。
8
5
 
9
6
 
10
-
11
-
12
-
13
- ```xaml
7
+ ```xml
14
-
15
8
  <Window
16
-
17
9
  x:Class="Questions355107.MainWindow"
18
-
19
10
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
20
-
21
11
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
22
-
23
12
  xmlns:local="clr-namespace:Questions355107"
24
-
25
13
  Width="{Binding Settings.Window.Width, Mode=TwoWay}"
26
-
27
14
  Height="{Binding Settings.Window.Height, Mode=TwoWay}"
28
-
29
15
  FontSize="30"
30
-
31
16
  FontWeight="Bold"
32
-
33
17
  Left="{Binding Settings.Window.Left, Mode=TwoWay}"
34
-
35
18
  Top="{Binding Settings.Window.Top, Mode=TwoWay}">
36
-
37
19
  <Window.DataContext>
38
-
39
20
  <local:ViewModel />
40
-
41
21
  </Window.DataContext>
42
-
43
22
  <Window.Resources>
44
-
45
23
  <Style TargetType="TextBlock">
46
-
47
24
  <Setter Property="HorizontalAlignment" Value="Center" />
48
-
49
25
  <Setter Property="VerticalAlignment" Value="Center" />
50
-
51
26
  </Style>
52
-
53
27
  <Style TargetType="GridSplitter">
54
-
55
28
  <Setter Property="HorizontalAlignment" Value="Stretch" />
56
-
57
29
  </Style>
58
-
59
30
  </Window.Resources>
60
-
61
31
  <DockPanel>
62
-
63
32
  <StackPanel
64
-
65
33
  HorizontalAlignment="Center"
66
-
67
34
  DockPanel.Dock="Top"
68
-
69
35
  Orientation="Horizontal">
70
-
71
36
  <Button Command="{Binding SaveCommand}" Content="Save" />
72
-
73
37
  <Button Command="{Binding LoadCommand}" Content="Load" />
74
-
75
38
  </StackPanel>
76
39
 
77
-
78
-
79
40
  <Grid>
80
-
81
41
  <Grid.ColumnDefinitions>
82
-
83
42
  <ColumnDefinition Width="{Binding Settings.Splitter.Outer1, Mode=TwoWay}" />
84
-
85
43
  <ColumnDefinition Width="5" />
86
-
87
44
  <ColumnDefinition Width="{Binding Settings.Splitter.Outer2, Mode=TwoWay}" />
88
-
89
45
  <ColumnDefinition Width="5" />
90
-
91
46
  <ColumnDefinition Width="{Binding Settings.Splitter.Outer3, Mode=TwoWay}" />
92
-
93
47
  </Grid.ColumnDefinitions>
94
-
95
48
  <Border Background="LightCoral">
96
-
97
49
  <!--<TextBlock Text="outer ①" />-->
98
-
99
50
  <Grid Margin="10">
100
-
101
51
  <Grid.RowDefinitions>
102
-
103
52
  <RowDefinition Height="{Binding Settings.Splitter.Inner1, Mode=TwoWay}" />
104
-
105
53
  <RowDefinition Height="5" />
106
-
107
54
  <RowDefinition Height="{Binding Settings.Splitter.Inner2, Mode=TwoWay}" />
108
-
109
55
  </Grid.RowDefinitions>
110
-
111
56
  <Border Background="Pink">
112
-
113
57
  <TextBlock Text="inner ①" />
114
-
115
58
  </Border>
116
-
117
-
118
59
 
119
60
  <GridSplitter Grid.Row="1" />
120
61
 
121
-
122
-
123
62
  <Border Grid.Row="2" Background="Orange">
124
-
125
63
  <TextBlock Text="inner ②" />
126
-
127
64
  </Border>
128
-
129
65
  </Grid>
130
-
131
66
  </Border>
132
-
133
-
134
67
 
135
68
  <GridSplitter Grid.Column="1" />
136
69
 
137
-
138
-
139
70
  <Border Grid.Column="2" Background="LightGreen">
140
-
141
71
  <TextBlock Text="outer ②" />
142
-
143
72
  </Border>
144
-
145
-
146
73
 
147
74
  <GridSplitter Grid.Column="3" />
148
75
 
149
-
150
-
151
76
  <Border Grid.Column="4" Background="SkyBlue">
152
-
153
77
  <TextBlock Text="outer ③" />
154
-
155
78
  </Border>
156
-
157
79
  </Grid>
158
-
159
80
  </DockPanel>
160
-
161
81
  </Window>
162
-
163
82
  ```
164
83
 
165
-
166
-
167
- ```C#
84
+ ```cs
168
-
169
85
  using CommunityToolkit.Mvvm.ComponentModel;
170
-
171
86
  using CommunityToolkit.Mvvm.Input;
172
-
173
87
  using System.Diagnostics;
174
-
175
88
  using System.Text.Json;
176
-
177
89
  using System.Text.Json.Serialization;
178
-
179
90
  using System.Windows;
180
91
 
181
92
 
182
-
183
-
184
-
185
93
  namespace Questions355107
186
-
187
94
  {
188
-
189
95
  public class WindowModel : ObservableObject
190
-
191
96
  {
192
-
193
97
  public double Top { get => _Top; set => SetProperty(ref _Top, value); }
194
-
195
98
  private double _Top = double.NaN; // 動かさずにSaveすると位置を復元しないが、普通そういうことにはならんでしょう
196
-
197
99
  public double Left { get => _Left; set => SetProperty(ref _Left, value); }
198
-
199
100
  private double _Left = double.NaN;
200
-
201
101
  public double Width { get => _Width; set => SetProperty(ref _Width, value); }
202
-
203
102
  private double _Width = 800;
204
-
205
103
  public double Height { get => _Height; set => SetProperty(ref _Height, value); }
206
-
207
104
  private double _Height = 450;
208
-
209
105
  }
210
106
 
211
-
212
-
213
107
  public class SplitterModel : ObservableObject
214
-
215
108
  {
216
-
217
109
  public string Outer1 { get => _Outer1; set => SetProperty(ref _Outer1, value); }
218
-
219
110
  private string _Outer1 = "200"; // Pixcel指定(何もしていないのではみ出ます^^;
220
-
221
111
  public string Outer2 { get => _Outer2; set => SetProperty(ref _Outer2, value); }
222
-
223
112
  private string _Outer2 = "1*"; // Star指定
224
-
225
113
  public string Outer3 { get => _Outer3; set => SetProperty(ref _Outer3, value); }
226
-
227
114
  private string _Outer3 = "2*";
228
-
229
115
  public string Inner1 { get => _Inner1; set => SetProperty(ref _Inner1, value); }
230
-
231
116
  private string _Inner1 = "1*";
232
-
233
117
  public string Inner2 { get => _Inner2; set => SetProperty(ref _Inner2, value); }
234
-
235
118
  private string _Inner2 = "1*";
236
-
237
119
  }
238
120
 
239
-
240
-
241
121
  public class SettingsModel
242
-
243
122
  {
244
-
245
123
  public WindowModel Window { get; set; } = new();
246
-
247
124
  public SplitterModel Splitter { get; set; } = new();
248
-
249
125
  }
250
126
 
251
-
252
-
253
127
  public class ViewModel : ObservableObject
254
-
255
128
  {
256
-
257
129
  public SettingsModel Settings { get => _Settings; set => SetProperty(ref _Settings, value); }
258
-
259
130
  private SettingsModel _Settings;
260
-
261
131
  public RelayCommand SaveCommand { get; }
262
-
263
132
  public RelayCommand LoadCommand { get; }
264
133
 
265
-
266
-
267
134
  private string settingsJson;
268
-
269
135
  private readonly JsonSerializerOptions options = new()
270
-
271
136
  {
272
-
273
137
  NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
274
-
275
138
  WriteIndented = true,
276
-
277
139
  };
278
140
 
279
141
 
280
-
281
-
282
-
283
142
  public ViewModel()
284
-
285
143
  {
286
-
287
144
  Settings = new(); // 本来はファイルから
288
145
 
289
-
290
-
291
146
  SaveCommand = new(() =>
292
-
293
147
  {
294
-
295
148
  // ファイルにセーブしたつもり
296
-
297
149
  settingsJson = JsonSerializer.Serialize(Settings, options);
298
-
299
150
  Debug.WriteLine(settingsJson);
300
-
301
151
  });
302
152
 
303
-
304
-
305
153
  LoadCommand = new(() =>
306
-
307
154
  {
308
-
309
155
  // 私は普段起動時に読むだけなのでPropertyChangedすらしないが、
310
-
311
156
  // 起動中に変更する場合nullでも入れてリセットしないとうまく反映されなかった(Topだけ入らない等
312
-
313
157
  Settings = null;
314
-
315
158
  // ファイルからロードしたつもり
316
-
317
159
  Settings = JsonSerializer.Deserialize<SettingsModel>(settingsJson, options);
318
-
319
160
  });
320
161
 
321
-
322
-
323
162
  SaveCommand.Execute(null); // ヌルリよけ
324
-
325
163
  }
326
-
327
164
  }
328
165
 
329
-
330
-
331
166
  public partial class MainWindow : Window
332
-
333
167
  {
334
-
335
168
  public MainWindow() => InitializeComponent();
336
-
337
169
  }
338
-
339
170
  }
340
-
341
171
  ```
342
-
343
172
  ![アプリ画像](5073ce60ed596c1b3ca2ce1be3106c79.png)
344
-
345
173
  `INotifyPropertyChanged`・`ICommand`実装は↓を使用しました。
346
-
347
174
  [NuGet Gallery | CommunityToolkit.Mvvm 7.0.3](https://www.nuget.org/packages/CommunityToolkit.Mvvm/7.0.3)
348
175
 
349
-
350
-
351
176
  .NET Core 3.1より前の場合は↓を入れてください。
352
-
353
177
  [NuGet Gallery | System.Text.Json 5.0.2](https://www.nuget.org/packages/System.Text.Json)
354
178
 
355
-
356
-
357
179
  C#9で書いたので`new()`でエラーが出たら型を書いてください。
358
-
359
180
  [Target-typed new expressions - C# 9.0 specification proposals | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/proposals/csharp-9.0/target-typed-new)