回答編集履歴

1

見直しキャンペーン中

2023/07/17 13:27

投稿

TN8001
TN8001

スコア9350

test CHANGED
@@ -1,373 +1,185 @@
1
- 1点目
1
+ ### 1点目
2
-
3
2
  xamlの間違いを直します。
4
-
5
- ```xaml
3
+ ```xml
6
-
7
4
  <TextBlock x:Name="TextBlock_Result" Text="{Binding Path=printText.Result}"/>
8
-
9
5
  <TextBlock x:Name="TextBlock_Filename" Text="{Binding filename.Filename}"/>
10
-
11
6
  ```
12
-
13
7
 
14
-
15
- ```xaml
8
+ ```xml
16
-
17
- <TextBlock x:Name="TextBlock_Result" Text="{Binding Path=PrintText.Result}"/>
9
+ <TextBlock x:Name="TextBlock_Result" Text="{Binding PrintText.Result}"/>
18
-
19
10
  <TextBlock x:Name="TextBlock_Filename" Text="{Binding PrintFilename.Filename}"/>
20
-
21
11
  ```
22
12
 
23
13
  バインディングのエラーは出力ウィンドウに出るだけで、特に止まったりしないので気が付きにくいです。
14
+ ```
15
+ System.Windows.Data Error: 40 : BindingExpression path error: 'printText' property not found on 'object' ''MainWindowViewModel' (HashCode=64554036)'. BindingExpression:Path=printText.Result; DataItem='MainWindowViewModel' (HashCode=64554036); target element is 'TextBlock' (Name='TextBlock_Result'); target property is 'Text' (type 'String')
16
+ System.Windows.Data Error: 40 : BindingExpression path error: 'filename' property not found on 'object' ''MainWindowViewModel' (HashCode=64554036)'. BindingExpression:Path=filename.Filename; DataItem='MainWindowViewModel' (HashCode=64554036); target element is 'TextBlock' (Name='TextBlock_Filename'); target property is 'Text' (type 'String')
17
+ ```
18
+ のようなエラーが出ているはずです。
24
19
 
20
+ ### 2点目
21
+ バインディングを使って表示したいのでしょうから、変更通知(`INotifyPropertyChanged`)の実装が必要になります(ViewModelBase・BindableBase・Observable等名前はいろいろだったりしますが、中身は大体同じで定型コードです)
22
+
23
+ `MainWindowViewModel`の`PrintText`・`PrintFilename`を丸ごと入れ替えるような想定であればこんな感じになります。
24
+ ```cs
25
+ using System.ComponentModel;
26
+ using System.Runtime.CompilerServices;
27
+ using System.Windows;
28
+ using Microsoft.Win32;
29
+
30
+ namespace Questions233114
31
+ {
32
+ class PrintFilename
33
+ {
34
+ public string Filename { get; set; }
35
+ }
36
+
37
+ class PrintText
38
+ {
39
+ public string Result { get; set; }
40
+ }
41
+
42
+ class MainWindowViewModel : Observable
43
+ {
44
+ public PrintText PrintText { get => _PrintText; set => Set(ref _PrintText, value); }
45
+ private PrintText _PrintText;
46
+ public PrintFilename PrintFilename { get => _PrintFilename; set => Set(ref _PrintFilename, value); }
47
+ private PrintFilename _PrintFilename;
48
+
49
+ public MainWindowViewModel()
50
+ {
51
+ PrintText = new PrintText();
52
+ PrintFilename = new PrintFilename();
53
+ }
54
+ }
55
+
56
+ abstract class Observable : INotifyPropertyChanged
57
+ {
58
+ public event PropertyChangedEventHandler PropertyChanged;
59
+ protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
60
+ {
61
+ if(Equals(storage, value)) return false;
62
+
63
+ storage = value;
64
+ OnPropertyChanged(propertyName);
65
+ return true;
66
+ }
67
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
68
+ => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
69
+ }
70
+
71
+ public partial class MainWindow : Window
72
+ {
73
+ private readonly MainWindowViewModel vm;
74
+ public MainWindow()
75
+ {
76
+ InitializeComponent();
77
+
78
+ vm = new MainWindowViewModel();
79
+ DataContext = vm;
80
+
81
+ var printText = new PrintText { Result = "OK" };
82
+ vm.PrintText = printText;
83
+
84
+ MessageBox.Show(vm.PrintText.Result);
85
+ }
86
+
87
+ private void Data_Button_Click(object sender, RoutedEventArgs e)
88
+ {
89
+ var oFileDialog = new OpenFileDialog { Filter = "Excel (*.xlsx)|*.xlsx" };
90
+
91
+ if(oFileDialog.ShowDialog() == false)
92
+ {
93
+ return;
94
+ }
95
+
96
+ var filename = new PrintFilename { Filename = oFileDialog.FileName };
97
+ vm.PrintFilename = filename;
98
+
99
+ MessageBox.Show(vm.PrintFilename.Filename);
100
+ }
101
+ }
102
+ }
25
103
  ```
26
104
 
27
- System.Windows.Data Error: 40 : BindingExpression path error: 'printText' property not found on 'object' ''MainWindowViewModel' (HashCode=64554036)'. BindingExpression:Path=printText.Result; DataItem='MainWindowViewModel' (HashCode=64554036); target element is 'TextBlock' (Name='TextBlock_Result'); target property is 'Text' (type 'String')
28
-
29
- System.Windows.Data Error: 40 : BindingExpression path error: 'filename' property not found on 'object' ''MainWindowViewModel' (HashCode=64554036)'. BindingExpression:Path=filename.Filename; DataItem='MainWindowViewModel' (HashCode=64554036); target element is 'TextBlock' (Name='TextBlock_Filename'); target property is 'Text' (type 'String')
30
-
31
- ```
32
-
33
- のようなエラーが出ているはずです。
34
-
35
-
36
-
37
- 2点目
38
-
39
- バインディングを使って表示したいのでしょうから、変更通知(INotifyPropertyChanged)の実装が必要になります。(ViewModelBase BindableBase Observable等名前はいろいろだったりしますが、中身は大体同じで定型コードです)
40
-
41
-
42
-
43
- MainWindowViewModelのPrintText・PrintFilenameを丸ごと入れ替えるような想定であれば
44
-
45
- ```C#
46
-
105
+ FilenameResultを直接変えるのであればこんな感じになります。
106
+ ```cs
47
107
  using System.ComponentModel;
48
-
49
108
  using System.Runtime.CompilerServices;
50
-
51
109
  using System.Windows;
52
-
53
110
  using Microsoft.Win32;
54
111
 
55
-
56
-
57
112
  namespace Questions233114
58
-
59
113
  {
60
-
61
- class PrintFilename
114
+ class PrintFilename : Observable
62
-
63
115
  {
64
-
116
+ public string Filename { get => _Filename; set => Set(ref _Filename, value); }
65
- public string Filename { get; set; }
117
+ private string _Filename;
66
-
67
118
  }
68
119
 
69
-
70
-
71
- class PrintText
120
+ class PrintText : Observable
72
-
73
121
  {
74
-
122
+ public string Result { get => _Result; set => Set(ref _Result, value); }
75
- public string Result { get; set; }
123
+ private string _Result;
76
-
77
124
  }
78
125
 
79
-
80
-
81
- class MainWindowViewModel : Observable
126
+ class MainWindowViewModel
82
-
83
127
  {
84
-
85
- public PrintText PrintText { get => _PrintText; set => Set(ref _PrintText, value); }
128
+ public PrintText PrintText { get; private set; }
86
-
87
- private PrintText _PrintText;
88
-
89
- public PrintFilename PrintFilename { get => _PrintFilename; set => Set(ref _PrintFilename, value); }
90
-
91
- private PrintFilename _PrintFilename;
129
+ public PrintFilename PrintFilename { get; private set; }
92
-
93
-
94
130
 
95
131
  public MainWindowViewModel()
96
-
97
132
  {
98
-
99
133
  PrintText = new PrintText();
100
-
101
134
  PrintFilename = new PrintFilename();
102
-
103
135
  }
104
-
105
136
  }
106
137
 
107
-
108
-
109
138
  abstract class Observable : INotifyPropertyChanged
110
-
111
139
  {
112
-
113
140
  public event PropertyChangedEventHandler PropertyChanged;
114
-
115
141
  protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
116
-
117
142
  {
118
-
119
143
  if(Equals(storage, value)) return false;
120
144
 
121
-
122
-
123
145
  storage = value;
124
-
125
146
  OnPropertyChanged(propertyName);
126
-
127
147
  return true;
128
-
129
148
  }
130
-
131
149
  protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
132
-
133
150
  => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
134
-
135
151
  }
136
152
 
137
-
138
-
139
153
  public partial class MainWindow : Window
140
-
141
154
  {
142
-
143
155
  private readonly MainWindowViewModel vm;
144
156
 
145
157
  public MainWindow()
146
-
147
158
  {
148
-
149
159
  InitializeComponent();
150
-
151
-
152
-
153
160
  vm = new MainWindowViewModel();
154
-
155
161
  DataContext = vm;
156
-
157
-
158
-
159
- var printText = new PrintText { Result = "OK" };
160
-
161
- vm.PrintText = printText;
162
-
163
-
164
-
165
- MessageBox.Show(vm.PrintText.Result);
166
-
167
- }
168
-
169
-
170
-
171
- private void Data_Button_Click(object sender, RoutedEventArgs e)
172
-
173
- {
174
-
175
- var oFileDialog = new OpenFileDialog { Filter = "Excel (*.xlsx)|*.xlsx" };
176
-
177
-
178
-
179
- if(oFileDialog.ShowDialog() == false)
180
-
181
- {
182
-
183
- return;
184
-
185
- }
186
-
187
-
188
-
189
- var filename = new PrintFilename { Filename = oFileDialog.FileName };
190
-
191
- vm.PrintFilename = filename;
192
-
193
-
194
-
195
- MessageBox.Show(vm.PrintFilename.Filename);
196
-
197
- }
198
-
199
- }
200
-
201
- }
202
-
203
- ```
204
-
205
- こんな感じになります。
206
-
207
-
208
-
209
-
210
-
211
- Filename・Resultを直接変えるのであれば
212
-
213
- ```C#
214
-
215
- using System.ComponentModel;
216
-
217
- using System.Runtime.CompilerServices;
218
-
219
- using System.Windows;
220
-
221
- using Microsoft.Win32;
222
-
223
-
224
-
225
- namespace Questions233114
226
-
227
- {
228
-
229
- class PrintFilename : Observable
230
-
231
- {
232
-
233
- public string Filename { get => _Filename; set => Set(ref _Filename, value); }
234
-
235
- private string _Filename;
236
-
237
- }
238
-
239
-
240
-
241
- class PrintText : Observable
242
-
243
- {
244
-
245
- public string Result { get => _Result; set => Set(ref _Result, value); }
246
-
247
- private string _Result;
248
-
249
- }
250
-
251
-
252
-
253
- class MainWindowViewModel
254
-
255
- {
256
-
257
- public PrintText PrintText { get; private set; }
258
-
259
- public PrintFilename PrintFilename { get; private set; }
260
-
261
-
262
-
263
- public MainWindowViewModel()
264
-
265
- {
266
-
267
- PrintText = new PrintText();
268
-
269
- PrintFilename = new PrintFilename();
270
-
271
- }
272
-
273
- }
274
-
275
-
276
-
277
- abstract class Observable : INotifyPropertyChanged
278
-
279
- {
280
-
281
- public event PropertyChangedEventHandler PropertyChanged;
282
-
283
- protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
284
-
285
- {
286
-
287
- if(Equals(storage, value)) return false;
288
-
289
-
290
-
291
- storage = value;
292
-
293
- OnPropertyChanged(propertyName);
294
-
295
- return true;
296
-
297
- }
298
-
299
- protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
300
-
301
- => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
302
-
303
- }
304
-
305
-
306
-
307
- public partial class MainWindow : Window
308
-
309
- {
310
-
311
- private readonly MainWindowViewModel vm;
312
-
313
-
314
-
315
- public MainWindow()
316
-
317
- {
318
-
319
- InitializeComponent();
320
-
321
- vm = new MainWindowViewModel();
322
-
323
- DataContext = vm;
324
-
325
-
326
162
 
327
163
  vm.PrintText.Result = "OK";
328
164
 
329
-
330
-
331
165
  MessageBox.Show(vm.PrintText.Result);
332
-
333
166
  }
334
167
 
335
-
336
-
337
168
  private void Data_Button_Click(object sender, RoutedEventArgs e)
338
-
339
169
  {
340
-
341
170
  var oFileDialog = new OpenFileDialog { Filter = "Excel (*.xlsx)|*.xlsx" };
342
171
 
343
-
344
-
345
172
  if(oFileDialog.ShowDialog() == false)
346
-
347
173
  {
348
-
349
174
  return;
350
-
351
175
  }
352
-
353
-
354
176
 
355
177
  vm.PrintFilename.Filename = oFileDialog.FileName;
356
178
 
357
-
358
-
359
179
  MessageBox.Show(vm.PrintFilename.Filename);
360
-
361
180
  }
362
-
363
181
  }
364
-
365
182
  }
366
-
367
183
  ```
368
184
 
369
- こんな感じになります。
370
-
371
-
372
-
373
185
  どちらのパターンもあり得ますが、どちらがいいかはこれだけだとちょっと判断できません。