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

回答編集履歴

1

見直しキャンペーン中

2023/07/28 16:41

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,180 +1,180 @@
1
- `GridLength`を文字列でバインドすると、`Star`・`Pixcel`両対応でいい感じでした。
2
-
3
- 再利用性のないユーザーコントロールに、`DependencyProperty`を生やすのは趣味でないのでベタ書きです(生やすなら汎用的に作りたいという意味です)
4
- ユーザーコントロールにするなら文字列(か`GridLength`)を中継する`DependencyProperty`を生やすだけです。
5
-
6
-
7
- ```xaml
8
- <Window
9
- x:Class="Questions355107.MainWindow"
10
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
11
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
12
- xmlns:local="clr-namespace:Questions355107"
13
- Width="{Binding Settings.Window.Width, Mode=TwoWay}"
14
- Height="{Binding Settings.Window.Height, Mode=TwoWay}"
15
- FontSize="30"
16
- FontWeight="Bold"
17
- Left="{Binding Settings.Window.Left, Mode=TwoWay}"
18
- Top="{Binding Settings.Window.Top, Mode=TwoWay}">
19
- <Window.DataContext>
20
- <local:ViewModel />
21
- </Window.DataContext>
22
- <Window.Resources>
23
- <Style TargetType="TextBlock">
24
- <Setter Property="HorizontalAlignment" Value="Center" />
25
- <Setter Property="VerticalAlignment" Value="Center" />
26
- </Style>
27
- <Style TargetType="GridSplitter">
28
- <Setter Property="HorizontalAlignment" Value="Stretch" />
29
- </Style>
30
- </Window.Resources>
31
- <DockPanel>
32
- <StackPanel
33
- HorizontalAlignment="Center"
34
- DockPanel.Dock="Top"
35
- Orientation="Horizontal">
36
- <Button Command="{Binding SaveCommand}" Content="Save" />
37
- <Button Command="{Binding LoadCommand}" Content="Load" />
38
- </StackPanel>
39
-
40
- <Grid>
41
- <Grid.ColumnDefinitions>
42
- <ColumnDefinition Width="{Binding Settings.Splitter.Outer1, Mode=TwoWay}" />
43
- <ColumnDefinition Width="5" />
44
- <ColumnDefinition Width="{Binding Settings.Splitter.Outer2, Mode=TwoWay}" />
45
- <ColumnDefinition Width="5" />
46
- <ColumnDefinition Width="{Binding Settings.Splitter.Outer3, Mode=TwoWay}" />
47
- </Grid.ColumnDefinitions>
48
- <Border Background="LightCoral">
49
- <!--<TextBlock Text="outer ①" />-->
50
- <Grid Margin="10">
51
- <Grid.RowDefinitions>
52
- <RowDefinition Height="{Binding Settings.Splitter.Inner1, Mode=TwoWay}" />
53
- <RowDefinition Height="5" />
54
- <RowDefinition Height="{Binding Settings.Splitter.Inner2, Mode=TwoWay}" />
55
- </Grid.RowDefinitions>
56
- <Border Background="Pink">
57
- <TextBlock Text="inner ①" />
58
- </Border>
59
-
60
- <GridSplitter Grid.Row="1" />
61
-
62
- <Border Grid.Row="2" Background="Orange">
63
- <TextBlock Text="inner ②" />
64
- </Border>
65
- </Grid>
66
- </Border>
67
-
68
- <GridSplitter Grid.Column="1" />
69
-
70
- <Border Grid.Column="2" Background="LightGreen">
71
- <TextBlock Text="outer ②" />
72
- </Border>
73
-
74
- <GridSplitter Grid.Column="3" />
75
-
76
- <Border Grid.Column="4" Background="SkyBlue">
77
- <TextBlock Text="outer ③" />
78
- </Border>
79
- </Grid>
80
- </DockPanel>
81
- </Window>
82
- ```
83
-
84
- ```C#
85
- using CommunityToolkit.Mvvm.ComponentModel;
86
- using CommunityToolkit.Mvvm.Input;
87
- using System.Diagnostics;
88
- using System.Text.Json;
89
- using System.Text.Json.Serialization;
90
- using System.Windows;
91
-
92
-
93
- namespace Questions355107
94
- {
95
- public class WindowModel : ObservableObject
96
- {
97
- public double Top { get => _Top; set => SetProperty(ref _Top, value); }
98
- private double _Top = double.NaN; // 動かさずにSaveすると位置を復元しないが、普通そういうことにはならんでしょう
99
- public double Left { get => _Left; set => SetProperty(ref _Left, value); }
100
- private double _Left = double.NaN;
101
- public double Width { get => _Width; set => SetProperty(ref _Width, value); }
102
- private double _Width = 800;
103
- public double Height { get => _Height; set => SetProperty(ref _Height, value); }
104
- private double _Height = 450;
105
- }
106
-
107
- public class SplitterModel : ObservableObject
108
- {
109
- public string Outer1 { get => _Outer1; set => SetProperty(ref _Outer1, value); }
110
- private string _Outer1 = "200"; // Pixcel指定(何もしていないのではみ出ます^^;
111
- public string Outer2 { get => _Outer2; set => SetProperty(ref _Outer2, value); }
112
- private string _Outer2 = "1*"; // Star指定
113
- public string Outer3 { get => _Outer3; set => SetProperty(ref _Outer3, value); }
114
- private string _Outer3 = "2*";
115
- public string Inner1 { get => _Inner1; set => SetProperty(ref _Inner1, value); }
116
- private string _Inner1 = "1*";
117
- public string Inner2 { get => _Inner2; set => SetProperty(ref _Inner2, value); }
118
- private string _Inner2 = "1*";
119
- }
120
-
121
- public class SettingsModel
122
- {
123
- public WindowModel Window { get; set; } = new();
124
- public SplitterModel Splitter { get; set; } = new();
125
- }
126
-
127
- public class ViewModel : ObservableObject
128
- {
129
- public SettingsModel Settings { get => _Settings; set => SetProperty(ref _Settings, value); }
130
- private SettingsModel _Settings;
131
- public RelayCommand SaveCommand { get; }
132
- public RelayCommand LoadCommand { get; }
133
-
134
- private string settingsJson;
135
- private readonly JsonSerializerOptions options = new()
136
- {
137
- NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
138
- WriteIndented = true,
139
- };
140
-
141
-
142
- public ViewModel()
143
- {
144
- Settings = new(); // 本来はファイルから
145
-
146
- SaveCommand = new(() =>
147
- {
148
- // ファイルにセーブしたつもり
149
- settingsJson = JsonSerializer.Serialize(Settings, options);
150
- Debug.WriteLine(settingsJson);
151
- });
152
-
153
- LoadCommand = new(() =>
154
- {
155
- // 私は普段起動時に読むだけなのでPropertyChangedすらしないが、
156
- // 起動中に変更する場合nullでも入れてリセットしないとうまく反映されなかった(Topだけ入らない等
157
- Settings = null;
158
- // ファイルからロードしたつもり
159
- Settings = JsonSerializer.Deserialize<SettingsModel>(settingsJson, options);
160
- });
161
-
162
- SaveCommand.Execute(null); // ヌルリよけ
163
- }
164
- }
165
-
166
- public partial class MainWindow : Window
167
- {
168
- public MainWindow() => InitializeComponent();
169
- }
170
- }
171
- ```
172
- ![アプリ画像](5073ce60ed596c1b3ca2ce1be3106c79.png)
173
- `INotifyPropertyChanged`・`ICommand`実装は↓を使用しました。
174
- [NuGet Gallery | CommunityToolkit.Mvvm 7.0.3](https://www.nuget.org/packages/CommunityToolkit.Mvvm/7.0.3)
175
-
176
- .NET Core 3.1より前の場合は↓を入れてください。
177
- [NuGet Gallery | System.Text.Json 5.0.2](https://www.nuget.org/packages/System.Text.Json)
178
-
179
- C#9で書いたので`new()`でエラーが出たら型を書いてください。
1
+ `GridLength`を文字列でバインドすると、`Star`・`Pixcel`両対応でいい感じでした。
2
+
3
+ 再利用性のないユーザーコントロールに、`DependencyProperty`を生やすのは趣味でないのでベタ書きです(生やすなら汎用的に作りたいという意味です)
4
+ ユーザーコントロールにするなら文字列(か`GridLength`)を中継する`DependencyProperty`を生やすだけです。
5
+
6
+
7
+ ```xml
8
+ <Window
9
+ x:Class="Questions355107.MainWindow"
10
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
11
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
12
+ xmlns:local="clr-namespace:Questions355107"
13
+ Width="{Binding Settings.Window.Width, Mode=TwoWay}"
14
+ Height="{Binding Settings.Window.Height, Mode=TwoWay}"
15
+ FontSize="30"
16
+ FontWeight="Bold"
17
+ Left="{Binding Settings.Window.Left, Mode=TwoWay}"
18
+ Top="{Binding Settings.Window.Top, Mode=TwoWay}">
19
+ <Window.DataContext>
20
+ <local:ViewModel />
21
+ </Window.DataContext>
22
+ <Window.Resources>
23
+ <Style TargetType="TextBlock">
24
+ <Setter Property="HorizontalAlignment" Value="Center" />
25
+ <Setter Property="VerticalAlignment" Value="Center" />
26
+ </Style>
27
+ <Style TargetType="GridSplitter">
28
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
29
+ </Style>
30
+ </Window.Resources>
31
+ <DockPanel>
32
+ <StackPanel
33
+ HorizontalAlignment="Center"
34
+ DockPanel.Dock="Top"
35
+ Orientation="Horizontal">
36
+ <Button Command="{Binding SaveCommand}" Content="Save" />
37
+ <Button Command="{Binding LoadCommand}" Content="Load" />
38
+ </StackPanel>
39
+
40
+ <Grid>
41
+ <Grid.ColumnDefinitions>
42
+ <ColumnDefinition Width="{Binding Settings.Splitter.Outer1, Mode=TwoWay}" />
43
+ <ColumnDefinition Width="5" />
44
+ <ColumnDefinition Width="{Binding Settings.Splitter.Outer2, Mode=TwoWay}" />
45
+ <ColumnDefinition Width="5" />
46
+ <ColumnDefinition Width="{Binding Settings.Splitter.Outer3, Mode=TwoWay}" />
47
+ </Grid.ColumnDefinitions>
48
+ <Border Background="LightCoral">
49
+ <!--<TextBlock Text="outer ①" />-->
50
+ <Grid Margin="10">
51
+ <Grid.RowDefinitions>
52
+ <RowDefinition Height="{Binding Settings.Splitter.Inner1, Mode=TwoWay}" />
53
+ <RowDefinition Height="5" />
54
+ <RowDefinition Height="{Binding Settings.Splitter.Inner2, Mode=TwoWay}" />
55
+ </Grid.RowDefinitions>
56
+ <Border Background="Pink">
57
+ <TextBlock Text="inner ①" />
58
+ </Border>
59
+
60
+ <GridSplitter Grid.Row="1" />
61
+
62
+ <Border Grid.Row="2" Background="Orange">
63
+ <TextBlock Text="inner ②" />
64
+ </Border>
65
+ </Grid>
66
+ </Border>
67
+
68
+ <GridSplitter Grid.Column="1" />
69
+
70
+ <Border Grid.Column="2" Background="LightGreen">
71
+ <TextBlock Text="outer ②" />
72
+ </Border>
73
+
74
+ <GridSplitter Grid.Column="3" />
75
+
76
+ <Border Grid.Column="4" Background="SkyBlue">
77
+ <TextBlock Text="outer ③" />
78
+ </Border>
79
+ </Grid>
80
+ </DockPanel>
81
+ </Window>
82
+ ```
83
+
84
+ ```cs
85
+ using CommunityToolkit.Mvvm.ComponentModel;
86
+ using CommunityToolkit.Mvvm.Input;
87
+ using System.Diagnostics;
88
+ using System.Text.Json;
89
+ using System.Text.Json.Serialization;
90
+ using System.Windows;
91
+
92
+
93
+ namespace Questions355107
94
+ {
95
+ public class WindowModel : ObservableObject
96
+ {
97
+ public double Top { get => _Top; set => SetProperty(ref _Top, value); }
98
+ private double _Top = double.NaN; // 動かさずにSaveすると位置を復元しないが、普通そういうことにはならんでしょう
99
+ public double Left { get => _Left; set => SetProperty(ref _Left, value); }
100
+ private double _Left = double.NaN;
101
+ public double Width { get => _Width; set => SetProperty(ref _Width, value); }
102
+ private double _Width = 800;
103
+ public double Height { get => _Height; set => SetProperty(ref _Height, value); }
104
+ private double _Height = 450;
105
+ }
106
+
107
+ public class SplitterModel : ObservableObject
108
+ {
109
+ public string Outer1 { get => _Outer1; set => SetProperty(ref _Outer1, value); }
110
+ private string _Outer1 = "200"; // Pixcel指定(何もしていないのではみ出ます^^;
111
+ public string Outer2 { get => _Outer2; set => SetProperty(ref _Outer2, value); }
112
+ private string _Outer2 = "1*"; // Star指定
113
+ public string Outer3 { get => _Outer3; set => SetProperty(ref _Outer3, value); }
114
+ private string _Outer3 = "2*";
115
+ public string Inner1 { get => _Inner1; set => SetProperty(ref _Inner1, value); }
116
+ private string _Inner1 = "1*";
117
+ public string Inner2 { get => _Inner2; set => SetProperty(ref _Inner2, value); }
118
+ private string _Inner2 = "1*";
119
+ }
120
+
121
+ public class SettingsModel
122
+ {
123
+ public WindowModel Window { get; set; } = new();
124
+ public SplitterModel Splitter { get; set; } = new();
125
+ }
126
+
127
+ public class ViewModel : ObservableObject
128
+ {
129
+ public SettingsModel Settings { get => _Settings; set => SetProperty(ref _Settings, value); }
130
+ private SettingsModel _Settings;
131
+ public RelayCommand SaveCommand { get; }
132
+ public RelayCommand LoadCommand { get; }
133
+
134
+ private string settingsJson;
135
+ private readonly JsonSerializerOptions options = new()
136
+ {
137
+ NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
138
+ WriteIndented = true,
139
+ };
140
+
141
+
142
+ public ViewModel()
143
+ {
144
+ Settings = new(); // 本来はファイルから
145
+
146
+ SaveCommand = new(() =>
147
+ {
148
+ // ファイルにセーブしたつもり
149
+ settingsJson = JsonSerializer.Serialize(Settings, options);
150
+ Debug.WriteLine(settingsJson);
151
+ });
152
+
153
+ LoadCommand = new(() =>
154
+ {
155
+ // 私は普段起動時に読むだけなのでPropertyChangedすらしないが、
156
+ // 起動中に変更する場合nullでも入れてリセットしないとうまく反映されなかった(Topだけ入らない等
157
+ Settings = null;
158
+ // ファイルからロードしたつもり
159
+ Settings = JsonSerializer.Deserialize<SettingsModel>(settingsJson, options);
160
+ });
161
+
162
+ SaveCommand.Execute(null); // ヌルリよけ
163
+ }
164
+ }
165
+
166
+ public partial class MainWindow : Window
167
+ {
168
+ public MainWindow() => InitializeComponent();
169
+ }
170
+ }
171
+ ```
172
+ ![アプリ画像](5073ce60ed596c1b3ca2ce1be3106c79.png)
173
+ `INotifyPropertyChanged`・`ICommand`実装は↓を使用しました。
174
+ [NuGet Gallery | CommunityToolkit.Mvvm 7.0.3](https://www.nuget.org/packages/CommunityToolkit.Mvvm/7.0.3)
175
+
176
+ .NET Core 3.1より前の場合は↓を入れてください。
177
+ [NuGet Gallery | System.Text.Json 5.0.2](https://www.nuget.org/packages/System.Text.Json)
178
+
179
+ C#9で書いたので`new()`でエラーが出たら型を書いてください。
180
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)