回答編集履歴

2

見直しキャンペーン中

2023/07/23 04:34

投稿

TN8001
TN8001

スコア9898

test CHANGED
@@ -1,239 +1,118 @@
1
1
  Aは`RelativeSource`を付けることはしません。
2
-
3
- コンストラクタで`DataContext = this;`として、
4
-
5
- `ItemsSource="{Binding AaaItemsSource}"`
2
+ コンストラクタで`DataContext = this;`として、`ItemsSource="{Binding AaaItemsSource}"`と書きます。
6
-
7
- と書きます。
8
-
9
3
  通常は`DataContext = new ViewModel();`と、`ViewModel`クラスを作ります。
10
4
 
11
-
12
-
13
5
  Bはそもそもバインドしていません。初期値として値を入れただけです(それで用が足りる場合は問題ありません)
14
-
15
6
  しかし`cb1.ItemsSource = Ccc.Ddd;`とすると**MVVM**から外れることになるので、バインドしてしまうかxamlで固定値を入れることが多いと思います。
16
-
17
- ```xaml
7
+ ```xml
18
-
19
8
  <ComboBox>
20
-
21
9
  <sys:String>A</sys:String>
22
-
23
10
  <sys:String>B</sys:String>
24
-
25
11
  <sys:String>C</sys:String>
26
-
27
12
  </ComboBox>
28
-
29
13
  ```
30
-
31
-
32
14
 
33
15
  ---
34
16
 
35
-
36
-
37
17
  `Dictionary`だと本質が見えにくいので、`string`の場合の例です(全く面白くありませんが^^;
38
-
39
18
  「確認」ボタンを押すと今の値を表示します。「倍!!」ボタンを押すと値が2倍に伸びます。
40
-
41
-
42
19
 
43
20
  Aは`View`から`ViewModel`への変更のみ反映します(`OneWayToSource`)
44
21
 
45
-
46
-
47
22
  Bはバインドしていないので何も起きません。
48
-
49
-
50
23
 
51
24
  Cは双方向に値が反映されます(`TwoWay`)
52
25
 
53
-
54
-
55
26
  [方法: バインディングの方向を指定する - WPF | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/how-to-specify-the-direction-of-the-binding)
56
-
57
-
58
27
 
59
28
  ABCどれを選択するかは、要件から自動的に決まります。
60
29
 
61
-
62
-
63
- ```xaml
30
+ ```xml
64
-
65
31
  <Window
66
-
67
32
  x:Class="Questions285969.MainWindow"
68
-
69
33
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
70
-
71
34
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
72
-
73
35
  xmlns:sys="clr-namespace:System;assembly=mscorlib"
74
-
75
36
  Width="800"
76
-
77
37
  Height="450">
78
38
 
79
-
80
-
81
39
  <StackPanel>
82
-
83
40
  <!--<ComboBox>
84
-
85
41
  <sys:String>A</sys:String>
86
-
87
42
  <sys:String>B</sys:String>
88
-
89
43
  <sys:String>C</sys:String>
90
-
91
44
  </ComboBox>-->
92
45
 
93
-
94
-
95
46
  <!-- A -->
96
-
97
47
  <TextBox Text="{Binding A}" />
98
48
 
99
-
100
-
101
49
  <!-- B -->
102
-
103
50
  <TextBox x:Name="textBox" />
104
-
105
51
  <!-- 意味的にはただこうしただけ -->
106
-
107
52
  <!--<TextBox Text="B" />-->
108
53
 
109
-
110
-
111
54
  <!-- C -->
112
-
113
55
  <TextBox Text="{Binding C}" />
114
56
 
115
-
116
-
117
57
  <Button Click="Button_Click" Content="確認" />
118
-
119
58
  <Button Click="Button_Click_1" Content="倍!!" />
120
-
121
59
  </StackPanel>
122
-
123
60
  </Window>
124
-
125
61
  ```
126
62
 
127
-
128
-
129
- ```C#
63
+ ```cs
130
-
131
64
  using System.ComponentModel;
132
-
133
65
  using System.Runtime.CompilerServices;
134
-
135
66
  using System.Windows;
136
67
 
137
-
138
-
139
68
  namespace Questions285969
140
-
141
69
  {
142
-
143
70
  public partial class MainWindow : Window, INotifyPropertyChanged
144
-
145
71
  {
146
-
147
72
  public string A { get; set; } = "A";
148
-
149
-
150
73
 
151
74
  private string B = "B";
152
75
 
153
-
154
-
155
76
  public string C { get => c; set => Set(ref c, value); }
156
-
157
77
  private string c = "C";
158
78
 
79
+ public MainWindow()
80
+ {
81
+ InitializeComponent();
82
+ DataContext = this;
83
+ textBox.Text = B;
84
+ }
159
85
 
86
+ private void Button_Click(object sender, RoutedEventArgs e)
87
+ {
88
+ MessageBox.Show($"A:{A}\nB:{B}\nC:{C}");
89
+
90
+ // もちろんこうすれば表示されますが、そういうことはやめましょうというのが「MVVMパターン」です
91
+ // (このイベントハンドラ自体MVVMから外れてしまっていますが、そこは本題ではないので^^;
92
+ //MessageBox.Show($"A:{A}\nB:{textBox.Text}\nC:{C}");
93
+ }
160
94
 
161
- public MainWindow()
95
+ private void Button_Click_1(object sender, RoutedEventArgs e)
96
+ {
97
+ A += A;
98
+ B += B;
99
+ C += C;
162
100
 
163
- {
164
-
165
- InitializeComponent();
101
+ // もちろんこうすれば変わりますが、以下略
166
-
167
- DataContext = this;
168
-
169
- textBox.Text = B;
102
+ //textBox.Text += textBox.Text;
170
-
171
103
  }
172
104
 
173
105
 
174
-
106
+ #region INotifyPropertyChanged
175
- private void Button_Click(object sender, RoutedEventArgs e)
107
+ public event PropertyChangedEventHandler PropertyChanged;
176
-
108
+ protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
177
109
  {
178
-
179
- MessageBox.Show($"A:{A}\nB:{B}\nC:{C}");
110
+ if(Equals(storage, value)) return;
180
-
181
-
182
-
183
- // もちろんこうすれば表示されますが、そういうことはやめましょうというのが「MVVMパターン」です
184
-
185
- // (このイベントハンドラ自体MVVMから外れてしまっていますが、そこは本題ではないので^^;
111
+ storage = value;
186
-
187
- //MessageBox.Show($"A:{A}\nB:{textBox.Text}\nC:{C}");
112
+ OnPropertyChanged(propertyName);
188
-
189
113
  }
190
-
191
-
192
-
193
- private void Button_Click_1(object sender, RoutedEventArgs e)
194
-
195
- {
196
-
197
- A += A;
198
-
199
- B += B;
200
-
201
- C += C;
202
-
203
-
204
-
205
- // もちろんこうすれば変わりますが、以下略
206
-
207
- //textBox.Text += textBox.Text;
208
-
209
- }
210
-
211
-
212
-
213
-
214
-
215
- #region INotifyPropertyChanged
216
-
217
- public event PropertyChangedEventHandler PropertyChanged;
218
-
219
- protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
220
-
221
- {
222
-
223
- if(Equals(storage, value)) return;
224
-
225
- storage = value;
226
-
227
- OnPropertyChanged(propertyName);
228
-
229
- }
230
-
231
114
  protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
232
-
233
115
  #endregion
234
-
235
116
  }
236
-
237
117
  }
238
-
239
118
  ```

1

修正

2020/08/19 21:45

投稿

TN8001
TN8001

スコア9898

test CHANGED
@@ -40,7 +40,7 @@
40
40
 
41
41
 
42
42
 
43
- Aは`View`から`ViewModel`への変更のみ反映します(`BindingMode.OneWayToSource`)
43
+ Aは`View`から`ViewModel`への変更のみ反映します(`OneWayToSource`)
44
44
 
45
45
 
46
46
 
@@ -48,7 +48,7 @@
48
48
 
49
49
 
50
50
 
51
- Cは双方向に値が反映されます(`BindingMode.TwoWay`)
51
+ Cは双方向に値が反映されます(`TwoWay`)
52
52
 
53
53
 
54
54