回答編集履歴

2

見直しキャンペーン中

2023/07/29 14:31

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -21,7 +21,7 @@
21
21
 
22
22
 
23
23
  MainWindow
24
- ```xaml
24
+ ```xml
25
25
  <Window
26
26
  x:Class="Q2x9yv8s160mb6u.MainWindow"
27
27
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -82,7 +82,7 @@
82
82
  </UniformGrid>
83
83
  </Window>
84
84
  ```
85
- ```C#
85
+ ```cs
86
86
  using System.Windows;
87
87
  using CommunityToolkit.Mvvm.ComponentModel;
88
88
  using CommunityToolkit.Mvvm.Input;
@@ -117,7 +117,7 @@
117
117
  ```
118
118
 
119
119
  UserControl1(部分ビュー的)
120
- ```xaml
120
+ ```xml
121
121
  <UserControl
122
122
  x:Class="Q2x9yv8s160mb6u.UserControl1"
123
123
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -129,7 +129,7 @@
129
129
  </StackPanel>
130
130
  </UserControl>
131
131
  ```
132
- ```C#
132
+ ```cs
133
133
  using System.Windows.Controls;
134
134
 
135
135
  namespace Q2x9yv8s160mb6u
@@ -142,7 +142,7 @@
142
142
  ```
143
143
 
144
144
  UserControl2(カスタムコントロール的)
145
- ```xaml
145
+ ```xml
146
146
  <UserControl
147
147
  x:Class="Q2x9yv8s160mb6u.UserControl2"
148
148
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -155,7 +155,7 @@
155
155
  </StackPanel>
156
156
  </UserControl>
157
157
  ```
158
- ```C#
158
+ ```cs
159
159
  using System.Windows;
160
160
  using System.Windows.Controls;
161
161
 
@@ -175,7 +175,7 @@
175
175
  ```
176
176
 
177
177
  UserControl3(オリジナル)
178
- ```xaml
178
+ ```xml
179
179
  <UserControl
180
180
  x:Class="Q2x9yv8s160mb6u.UserControl3"
181
181
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -187,7 +187,7 @@
187
187
  </StackPanel>
188
188
  </UserControl>
189
189
  ```
190
- ```C#
190
+ ```cs
191
191
  using System.Windows;
192
192
  using System.Windows.Controls;
193
193
  using System.Windows.Data;
@@ -213,7 +213,7 @@
213
213
  ```
214
214
 
215
215
  UserControl4(継承)
216
- ```xaml
216
+ ```xml
217
217
  <local:UserControl4Base
218
218
  x:Class="Q2x9yv8s160mb6u.UserControl4"
219
219
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -227,7 +227,7 @@
227
227
  </StackPanel>
228
228
  </local:UserControl4Base>
229
229
  ```
230
- ```C#
230
+ ```cs
231
231
  using System.Windows;
232
232
  using System.Windows.Controls;
233
233
 
@@ -253,7 +253,7 @@
253
253
  ```
254
254
 
255
255
  UserControl5(添付プロパティ)
256
- ```xaml
256
+ ```xml
257
257
  <UserControl
258
258
  x:Class="Q2x9yv8s160mb6u.UserControl5"
259
259
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -267,7 +267,7 @@
267
267
  </StackPanel>
268
268
  </UserControl>
269
269
  ```
270
- ```C#
270
+ ```cs
271
271
  using System.Windows;
272
272
  using System.Windows.Controls;
273
273
 

1

無理やりMVVM

2022/01/24 11:14

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -1,13 +1,24 @@
1
1
  回答しないといいましたが、コメントだけでは伝えられそうにないので回答します^^;
2
2
  文字数制限があるので可能な限りシンプルに、`NumericUpDown`を題材にさせていただきました(超雑なのは目をつぶってください^^;
3
3
 
4
+ 6パターンあります。
5
+ * ベタ置き
6
+ * 部分ビュー的
4
- 4パターン(ベタ置き・部分ビュー的・カスタムコントロール的・得体の知れないもの、が)あります。
7
+ * カスタムコントロール的
8
+ * オリジナル
9
+ * 継承
10
+ * 添付プロパティ
11
+
5
12
  イメージとしてはベタ置きで書いていたがゴチャついてきたので、部分ビュー的に切り出した。
6
13
  その後複数個使いたくなったので、カスタムコントロール的に作り替えたといった感じです。
7
14
  もちろん`NumericUpDown`ならカスタムコントロールにするのがベストですが、使いまわす気がないなら手前で留めておくのもありです。
8
15
 
16
+
17
+ > MVVMで実装する前提で回答を頂けるとありがたいです。
18
+
9
- 得体知れないものは、部分ビュー・カスタムコントロール的を合体させたような感じになってす。
19
+ ことですで後半3つ無理やり作りましたが個人的には意味が分かんない
10
- 両方の面倒なところ合わさったというか無駄にまどろっこしいというか、「それ何の意味があるの?」感が伝わりますかね?^^;
20
+ 部分ビュー的・カスタムコントロール的の面倒なところをわざわざ合わたというか無駄にまどろっこしいというか、「それ何の意味があるの?」感が伝わりますかね?^^;
21
+
11
22
 
12
23
  MainWindow
13
24
  ```xaml
@@ -21,7 +32,7 @@
21
32
  <Window.DataContext>
22
33
  <local:MainViewModel />
23
34
  </Window.DataContext>
24
- <UniformGrid Columns="2">
35
+ <UniformGrid Columns="3">
25
36
  <GroupBox Header="ベタ置き">
26
37
  <StackPanel>
27
38
  <TextBlock Text="{Binding Value}" />
@@ -42,18 +53,30 @@
42
53
  <StackPanel>
43
54
  <local:UserControl2 x:Name="userControl2" />
44
55
  <TextBlock Text="{Binding Value, ElementName=userControl2, StringFormat=今の値は {0} です}" />
45
- <!-- もちろんこうなっていてもいい -->
56
+ <!-- もちろんこうなっていてもいい(以下3・4・5も同様) -->
46
57
  <!--<local:UserControl2 Value="{Binding Hoge}" />
47
58
  <TextBlock Text="{Binding Hoge, StringFormat=今の値は {0} です}" />-->
48
59
  </StackPanel>
49
60
  </GroupBox>
50
61
 
51
- <GroupBox Header="得体の知れないもの">
62
+ <GroupBox Header="オリジナル">
52
63
  <StackPanel>
53
64
  <local:UserControl3 x:Name="userControl3" />
54
65
  <TextBlock Text="{Binding Value, ElementName=userControl3, StringFormat=今の値は {0} です}" />
66
+ </StackPanel>
67
+ </GroupBox>
68
+
69
+ <GroupBox Header="継承">
70
+ <StackPanel>
55
- <!--<local:UserControl3 Value="{Binding Fuga}" />
71
+ <local:UserControl4 x:Name="userControl4" />
56
- <TextBlock Text="{Binding Fuga, StringFormat=今の値は {0} です}" />-->
72
+ <TextBlock Text="{Binding Value, ElementName=userControl4, StringFormat=今の値は {0} です}" />
73
+ </StackPanel>
74
+ </GroupBox>
75
+
76
+ <GroupBox Header="添付プロパティ">
77
+ <StackPanel>
78
+ <local:UserControl5 x:Name="userControl5" />
79
+ <TextBlock Text="{Binding (local:UserControl5.Value), ElementName=userControl5, StringFormat=今の値は {0} です}" />
57
80
  </StackPanel>
58
81
  </GroupBox>
59
82
  </UniformGrid>
@@ -66,7 +89,7 @@
66
89
 
67
90
  namespace Q2x9yv8s160mb6u
68
91
  {
69
- public class MainViewModel : ObservableObject
92
+ public class UserControlViewModel : ObservableObject
70
93
  {
71
94
  public int Value { get => _Value; set => SetProperty(ref _Value, value); }
72
95
  private int _Value;
@@ -74,15 +97,18 @@
74
97
  public RelayCommand IncrementCommand { get; }
75
98
  public RelayCommand DecrementCommand { get; }
76
99
 
77
- public UserControl1ViewModel UserControl1ViewModel { get; } = new();
78
-
79
- public MainViewModel()
100
+ public UserControlViewModel()
80
101
  {
81
102
  IncrementCommand = new(() => Value++);
82
103
  DecrementCommand = new(() => Value--);
83
104
  }
84
105
  }
85
106
 
107
+ public class MainViewModel : UserControlViewModel // 同じものを書くのが無駄なので継承で済ませた^^;
108
+ {
109
+ public UserControlViewModel UserControl1ViewModel { get; } = new();
110
+ }
111
+
86
112
  public partial class MainWindow : Window
87
113
  {
88
114
  public MainWindow() => InitializeComponent();
@@ -105,26 +131,9 @@
105
131
  ```
106
132
  ```C#
107
133
  using System.Windows.Controls;
108
- using CommunityToolkit.Mvvm.ComponentModel;
134
+
109
- using CommunityToolkit.Mvvm.Input;
110
-
111
- namespace Q2x9yv8s160mb6u
135
+ namespace Q2x9yv8s160mb6u
112
- {
136
+ {
113
- public class UserControl1ViewModel : ObservableObject
114
- {
115
- public int Value { get => _Value; set => SetProperty(ref _Value, value); }
116
- private int _Value;
117
-
118
- public RelayCommand IncrementCommand { get; }
119
- public RelayCommand DecrementCommand { get; }
120
-
121
- public UserControl1ViewModel()
122
- {
123
- IncrementCommand = new(() => Value++);
124
- DecrementCommand = new(() => Value--);
125
- }
126
- }
127
-
128
137
  public partial class UserControl1 : UserControl
129
138
  {
130
139
  public UserControl1() => InitializeComponent();
@@ -155,9 +164,7 @@
155
164
  public partial class UserControl2 : UserControl
156
165
  {
157
166
  public int Value { get => (int)GetValue(ValueProperty); set => SetValue(ValueProperty, value); }
158
- public static readonly DependencyProperty ValueProperty
159
- = DependencyProperty.Register(nameof(Value), typeof(int), typeof(UserControl2),
167
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(int), typeof(UserControl2), new PropertyMetadata(0));
160
- new PropertyMetadata(0));
161
168
 
162
169
  public UserControl2() => InitializeComponent();
163
170
 
@@ -167,7 +174,7 @@
167
174
  }
168
175
  ```
169
176
 
170
- UserControl3(得体の知れないもの
177
+ UserControl3(オリジナル
171
178
  ```xaml
172
179
  <UserControl
173
180
  x:Class="Q2x9yv8s160mb6u.UserControl3"
@@ -183,42 +190,101 @@
183
190
  ```C#
184
191
  using System.Windows;
185
192
  using System.Windows.Controls;
186
- using CommunityToolkit.Mvvm.ComponentModel;
187
- using CommunityToolkit.Mvvm.Input;
193
+ using System.Windows.Data;
188
-
194
+
189
- namespace Q2x9yv8s160mb6u
195
+ namespace Q2x9yv8s160mb6u
190
- {
196
+ {
191
- public class UserControl3ViewModel : ObservableObject
192
- {
193
- public int Value { get => _Value; set => SetProperty(ref _Value, value); }
194
- private int _Value;
195
-
196
- public RelayCommand IncrementCommand { get; }
197
- public RelayCommand DecrementCommand { get; }
198
-
199
- public UserControl3ViewModel()
200
- {
201
- IncrementCommand = new(() => Value++);
202
- DecrementCommand = new(() => Value--);
203
- }
204
- }
205
-
206
197
  public partial class UserControl3 : UserControl
207
198
  {
208
199
  public int Value { get => (int)GetValue(ValueProperty); set => SetValue(ValueProperty, value); }
209
- public static readonly DependencyProperty ValueProperty
210
- = DependencyProperty.Register(nameof(Value), typeof(int), typeof(UserControl3),
200
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(int), typeof(UserControl3), new PropertyMetadata(0));
211
- new PropertyMetadata(0));
212
-
213
- private readonly UserControl3ViewModel vm = new();
214
201
 
215
202
  public UserControl3()
216
203
  {
217
204
  InitializeComponent();
205
+ var vm = new UserControlViewModel();
206
+ //vm.PropertyChanged += (s, e) => Value = vm.Value;
207
+ // コードでバインドする?
208
+ SetBinding(ValueProperty, new Binding(nameof(vm.Value)));
218
209
  DataContext = vm;
219
- vm.PropertyChanged += (s, e) => Value = vm.Value;
220
- }
210
+ }
221
- }
211
+ }
222
- }
212
+ }
223
- ```
213
+ ```
214
+
224
-
215
+ UserControl4(継承)
216
+ ```xaml
217
+ <local:UserControl4Base
218
+ x:Class="Q2x9yv8s160mb6u.UserControl4"
219
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
220
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
221
+ xmlns:local="clr-namespace:Q2x9yv8s160mb6u"
222
+ Value="{Binding Value}">
223
+ <StackPanel>
224
+ <TextBlock Text="{Binding Value}" />
225
+ <RepeatButton Command="{Binding IncrementCommand}" Content="Up" />
226
+ <RepeatButton Command="{Binding DecrementCommand}" Content="Down" />
227
+ </StackPanel>
228
+ </local:UserControl4Base>
229
+ ```
230
+ ```C#
231
+ using System.Windows;
232
+ using System.Windows.Controls;
233
+
234
+ namespace Q2x9yv8s160mb6u
235
+ {
236
+ // <local:UserControl4Base x:Class="Q2x9yv8s160mb6u.UserControl4" Value="{Binding Value}">
237
+ // こう書けるようにするため、仕方なく間にクラスを挟む
238
+ public class UserControl4Base : UserControl
239
+ {
240
+ public int Value { get => (int)GetValue(ValueProperty); set => SetValue(ValueProperty, value); }
241
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(int), typeof(UserControl4Base), new PropertyMetadata(0));
242
+ }
243
+
244
+ public partial class UserControl4 : UserControl4Base
245
+ {
246
+ public UserControl4()
247
+ {
248
+ InitializeComponent();
249
+ DataContext = new UserControlViewModel();
250
+ }
251
+ }
252
+ }
253
+ ```
254
+
255
+ UserControl5(添付プロパティ)
256
+ ```xaml
257
+ <UserControl
258
+ x:Class="Q2x9yv8s160mb6u.UserControl5"
259
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
260
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
261
+ xmlns:local="clr-namespace:Q2x9yv8s160mb6u"
262
+ local:UserControl5.Value="{Binding Value}">
263
+ <StackPanel>
264
+ <TextBlock Text="{Binding Value}" />
265
+ <RepeatButton Command="{Binding IncrementCommand}" Content="Up" />
266
+ <RepeatButton Command="{Binding DecrementCommand}" Content="Down" />
267
+ </StackPanel>
268
+ </UserControl>
269
+ ```
270
+ ```C#
271
+ using System.Windows;
272
+ using System.Windows.Controls;
273
+
274
+ namespace Q2x9yv8s160mb6u
275
+ {
276
+ public partial class UserControl5 : UserControl
277
+ {
278
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached("Value", typeof(int), typeof(UserControl5), new PropertyMetadata(0));
279
+ public static int GetValue(DependencyObject obj) => (int)obj.GetValue(ValueProperty);
280
+ public static void SetValue(DependencyObject obj, int value) => obj.SetValue(ValueProperty, value);
281
+
282
+ public UserControl5()
283
+ {
284
+ InitializeComponent();
285
+ DataContext = new UserControlViewModel();
286
+ }
287
+ }
288
+ }
289
+ ```
290
+ ![アプリ画像](https://ddjkaamml8q8x.cloudfront.net/questions/2022-01-24/7af7cd21-d841-4266-aa6f-2c6939c63acb.png)