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

回答編集履歴

1

見直しキャンペーン中

2023/07/17 13:27

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,187 +1,185 @@
1
- 1点目
2
- xamlの間違いを直します。
3
- ```xaml
4
- <TextBlock x:Name="TextBlock_Result" Text="{Binding Path=printText.Result}"/>
5
- <TextBlock x:Name="TextBlock_Filename" Text="{Binding filename.Filename}"/>
6
- ```
7
-
8
- ```xaml
9
- <TextBlock x:Name="TextBlock_Result" Text="{Binding Path=PrintText.Result}"/>
10
- <TextBlock x:Name="TextBlock_Filename" Text="{Binding PrintFilename.Filename}"/>
11
- ```
12
- バインディングのエラーは出力ウィンドウに出るだけで、特に止まったりしないので気が付きにくいです。
13
- ```
14
- 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')
15
- 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')
16
- ```
17
- のようなエラーが出ているはずです。
18
-
19
- 2点目
20
- バインディングを使って表示したいのでしょうから、変更通知(INotifyPropertyChanged)の実装が必要になります。(ViewModelBase BindableBase Observable等名前はいろいろだったりしますが、中身は大体同じで定型コードです)
21
-
22
- MainWindowViewModelのPrintText・PrintFilenameを丸ごと入れ替えるような想定であれば
23
- ```C#
24
- using System.ComponentModel;
25
- using System.Runtime.CompilerServices;
26
- using System.Windows;
27
- using Microsoft.Win32;
28
-
29
- namespace Questions233114
30
- {
31
- class PrintFilename
32
- {
33
- public string Filename { get; set; }
34
- }
35
-
36
- class PrintText
37
- {
38
- public string Result { get; set; }
39
- }
40
-
41
- class MainWindowViewModel : Observable
42
- {
43
- public PrintText PrintText { get => _PrintText; set => Set(ref _PrintText, value); }
44
- private PrintText _PrintText;
45
- public PrintFilename PrintFilename { get => _PrintFilename; set => Set(ref _PrintFilename, value); }
46
- private PrintFilename _PrintFilename;
47
-
48
- public MainWindowViewModel()
49
- {
50
- PrintText = new PrintText();
51
- PrintFilename = new PrintFilename();
52
- }
53
- }
54
-
55
- abstract class Observable : INotifyPropertyChanged
56
- {
57
- public event PropertyChangedEventHandler PropertyChanged;
58
- protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
59
- {
60
- if(Equals(storage, value)) return false;
61
-
62
- storage = value;
63
- OnPropertyChanged(propertyName);
64
- return true;
65
- }
66
- protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
67
- => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
68
- }
69
-
70
- public partial class MainWindow : Window
71
- {
72
- private readonly MainWindowViewModel vm;
73
- public MainWindow()
74
- {
75
- InitializeComponent();
76
-
77
- vm = new MainWindowViewModel();
78
- DataContext = vm;
79
-
80
- var printText = new PrintText { Result = "OK" };
81
- vm.PrintText = printText;
82
-
83
- MessageBox.Show(vm.PrintText.Result);
84
- }
85
-
86
- private void Data_Button_Click(object sender, RoutedEventArgs e)
87
- {
88
- var oFileDialog = new OpenFileDialog { Filter = "Excel (*.xlsx)|*.xlsx" };
89
-
90
- if(oFileDialog.ShowDialog() == false)
91
- {
92
- return;
93
- }
94
-
95
- var filename = new PrintFilename { Filename = oFileDialog.FileName };
96
- vm.PrintFilename = filename;
97
-
98
- MessageBox.Show(vm.PrintFilename.Filename);
99
- }
100
- }
101
- }
102
- ```
103
- こんな感じになります。
104
-
105
-
106
- Filename・Resultを直接変えるのであれば
107
- ```C#
108
- using System.ComponentModel;
109
- using System.Runtime.CompilerServices;
110
- using System.Windows;
111
- using Microsoft.Win32;
112
-
113
- namespace Questions233114
114
- {
115
- class PrintFilename : Observable
116
- {
117
- public string Filename { get => _Filename; set => Set(ref _Filename, value); }
118
- private string _Filename;
119
- }
120
-
121
- class PrintText : Observable
122
- {
123
- public string Result { get => _Result; set => Set(ref _Result, value); }
124
- private string _Result;
125
- }
126
-
127
- class MainWindowViewModel
128
- {
129
- public PrintText PrintText { get; private set; }
130
- public PrintFilename PrintFilename { get; private set; }
131
-
132
- public MainWindowViewModel()
133
- {
134
- PrintText = new PrintText();
135
- PrintFilename = new PrintFilename();
136
- }
137
- }
138
-
139
- abstract class Observable : INotifyPropertyChanged
140
- {
141
- public event PropertyChangedEventHandler PropertyChanged;
142
- protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
143
- {
144
- if(Equals(storage, value)) return false;
145
-
146
- storage = value;
147
- OnPropertyChanged(propertyName);
148
- return true;
149
- }
150
- protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
151
- => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
152
- }
153
-
154
- public partial class MainWindow : Window
155
- {
156
- private readonly MainWindowViewModel vm;
157
-
158
- public MainWindow()
159
- {
160
- InitializeComponent();
161
- vm = new MainWindowViewModel();
162
- DataContext = vm;
163
-
164
- vm.PrintText.Result = "OK";
165
-
166
- MessageBox.Show(vm.PrintText.Result);
167
- }
168
-
169
- private void Data_Button_Click(object sender, RoutedEventArgs e)
170
- {
171
- var oFileDialog = new OpenFileDialog { Filter = "Excel (*.xlsx)|*.xlsx" };
172
-
173
- if(oFileDialog.ShowDialog() == false)
174
- {
175
- return;
176
- }
177
-
178
- vm.PrintFilename.Filename = oFileDialog.FileName;
179
-
180
- MessageBox.Show(vm.PrintFilename.Filename);
181
- }
182
- }
183
- }
184
- ```
185
- こんな感じになります。
186
-
1
+ ### 1点目
2
+ xamlの間違いを直します。
3
+ ```xml
4
+ <TextBlock x:Name="TextBlock_Result" Text="{Binding Path=printText.Result}"/>
5
+ <TextBlock x:Name="TextBlock_Filename" Text="{Binding filename.Filename}"/>
6
+ ```
7
+
8
+ ```xml
9
+ <TextBlock x:Name="TextBlock_Result" Text="{Binding PrintText.Result}"/>
10
+ <TextBlock x:Name="TextBlock_Filename" Text="{Binding PrintFilename.Filename}"/>
11
+ ```
12
+
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
+ のようなエラーが出ているはずです。
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
+ }
103
+ ```
104
+
105
+ Filename・Resultを直接変えるのであればこんな感じになります。
106
+ ```cs
107
+ using System.ComponentModel;
108
+ using System.Runtime.CompilerServices;
109
+ using System.Windows;
110
+ using Microsoft.Win32;
111
+
112
+ namespace Questions233114
113
+ {
114
+ class PrintFilename : Observable
115
+ {
116
+ public string Filename { get => _Filename; set => Set(ref _Filename, value); }
117
+ private string _Filename;
118
+ }
119
+
120
+ class PrintText : Observable
121
+ {
122
+ public string Result { get => _Result; set => Set(ref _Result, value); }
123
+ private string _Result;
124
+ }
125
+
126
+ class MainWindowViewModel
127
+ {
128
+ public PrintText PrintText { get; private set; }
129
+ public PrintFilename PrintFilename { get; private set; }
130
+
131
+ public MainWindowViewModel()
132
+ {
133
+ PrintText = new PrintText();
134
+ PrintFilename = new PrintFilename();
135
+ }
136
+ }
137
+
138
+ abstract class Observable : INotifyPropertyChanged
139
+ {
140
+ public event PropertyChangedEventHandler PropertyChanged;
141
+ protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
142
+ {
143
+ if(Equals(storage, value)) return false;
144
+
145
+ storage = value;
146
+ OnPropertyChanged(propertyName);
147
+ return true;
148
+ }
149
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
150
+ => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
151
+ }
152
+
153
+ public partial class MainWindow : Window
154
+ {
155
+ private readonly MainWindowViewModel vm;
156
+
157
+ public MainWindow()
158
+ {
159
+ InitializeComponent();
160
+ vm = new MainWindowViewModel();
161
+ DataContext = vm;
162
+
163
+ vm.PrintText.Result = "OK";
164
+
165
+ MessageBox.Show(vm.PrintText.Result);
166
+ }
167
+
168
+ private void Data_Button_Click(object sender, RoutedEventArgs e)
169
+ {
170
+ var oFileDialog = new OpenFileDialog { Filter = "Excel (*.xlsx)|*.xlsx" };
171
+
172
+ if(oFileDialog.ShowDialog() == false)
173
+ {
174
+ return;
175
+ }
176
+
177
+ vm.PrintFilename.Filename = oFileDialog.FileName;
178
+
179
+ MessageBox.Show(vm.PrintFilename.Filename);
180
+ }
181
+ }
182
+ }
183
+ ```
184
+
187
185
  どちらのパターンもあり得ますが、どちらがいいかはこれだけだとちょっと判断できません。