回答編集履歴

2

xmlから読み込んだ内容をTree構造に変えた

2017/08/31 13:22

投稿

IYEMON018
IYEMON018

スコア202

test CHANGED
@@ -231,3 +231,75 @@
231
231
 
232
232
 
233
233
  これでボタンをクリックすれば"名無しさん"が追加されます。
234
+
235
+
236
+
237
+ <追記2>
238
+
239
+ 確かにTree構造になっていませんでしたw
240
+
241
+
242
+
243
+ ```cs
244
+
245
+ PeopleTree = new ObservableCollection<PersonViewModel>(people.person.Select(x => new PersonViewModel { Name = x.Name }));
246
+
247
+ ```
248
+
249
+
250
+
251
+ ここを以下のように変更すればxml ファイルのpeople タグにあるName を表示することができます。
252
+
253
+
254
+
255
+ ```cs
256
+
257
+ PeopleTree = new ObservableCollection<PersonViewModel>();
258
+
259
+ PeopleTree.Add(new PersonViewModel
260
+
261
+ {
262
+
263
+ Name = people.Name
264
+
265
+ , Child = new ObservableCollection<PersonViewModel>(people.person.Select(x => new PersonViewModel { Name = x.Name }))
266
+
267
+ });
268
+
269
+ ```
270
+
271
+
272
+
273
+ ```cs
274
+
275
+ private void addPersonMethod()
276
+
277
+ {
278
+
279
+ PeopleTree.Add(new PersonViewModel { Name = "名無しさん", });
280
+
281
+ }
282
+
283
+ ```
284
+
285
+
286
+
287
+ ついでにこれも以下のように変更したほうがいいでしょう。
288
+
289
+
290
+
291
+ ```cs
292
+
293
+ private void addPersonMethod()
294
+
295
+ {
296
+
297
+ PeopleTree[0].Child.Add(new PersonViewModel { Name = "名無しさん", });
298
+
299
+ }
300
+
301
+ ```
302
+
303
+
304
+
305
+ こんな感じですね。

1

動くようなコードを追加

2017/08/31 13:22

投稿

IYEMON018
IYEMON018

スコア202

test CHANGED
@@ -9,3 +9,225 @@
9
9
  System.Xml.XmlAttribute は、INotifyPropertyChanged を実装していないので値を変更しても変更通知がView に通知されません。
10
10
 
11
11
  指定のXML をINotifyPropertyChanged を実装したクラスへ変換し、バインドすれば実現できるはずです。
12
+
13
+
14
+
15
+ <追記>
16
+
17
+ 回答欄にコード貼り付けられないのでこちらから回答させていただきます。
18
+
19
+
20
+
21
+ まずは、xmlの変換先のクラスを用意します。
22
+
23
+ ```cs
24
+
25
+ /// <remarks/>
26
+
27
+ [Serializable()]
28
+
29
+ [DesignerCategory("code")]
30
+
31
+ [XmlType(AnonymousType = true)]
32
+
33
+ [XmlRoot(Namespace = "", IsNullable = false)]
34
+
35
+ public partial class people
36
+
37
+ {
38
+
39
+
40
+
41
+ private peoplePerson[] personField;
42
+
43
+
44
+
45
+ private string nameField;
46
+
47
+
48
+
49
+ /// <remarks/>
50
+
51
+ [XmlElement("person")]
52
+
53
+ public peoplePerson[] person
54
+
55
+ {
56
+
57
+ get { return this.personField; }
58
+
59
+ set { this.personField = value; }
60
+
61
+ }
62
+
63
+
64
+
65
+ /// <remarks/>
66
+
67
+ [XmlAttribute()]
68
+
69
+ public string Name
70
+
71
+ {
72
+
73
+ get { return this.nameField; }
74
+
75
+ set { this.nameField = value; }
76
+
77
+ }
78
+
79
+ }
80
+
81
+
82
+
83
+ /// <remarks/>
84
+
85
+ [SerializableAttribute()]
86
+
87
+ [DesignerCategoryAttribute("code")]
88
+
89
+ [XmlType(AnonymousType = true)]
90
+
91
+ public partial class peoplePerson
92
+
93
+ {
94
+
95
+ private string nameField;
96
+
97
+
98
+
99
+ /// <remarks/>
100
+
101
+ [XmlAttribute()]
102
+
103
+ public string Name
104
+
105
+ {
106
+
107
+ get { return this.nameField; }
108
+
109
+ set { this.nameField = value; }
110
+
111
+ }
112
+
113
+ }
114
+
115
+ ```
116
+
117
+
118
+
119
+ つぎに、xmlのpersonタグの要素と対になる、画面にバインドするためのクラスを作成します。
120
+
121
+ ```cs
122
+
123
+
124
+
125
+ public class PersonViewModel : BindableBase
126
+
127
+ {
128
+
129
+ private string name;
130
+
131
+ public string Name
132
+
133
+ {
134
+
135
+ get { return name; }
136
+
137
+ set { SetProperty(ref name, value); }
138
+
139
+ }
140
+
141
+
142
+
143
+ public ObservableCollection<PersonViewModel> Child { get; set; }
144
+
145
+ }
146
+
147
+ ```
148
+
149
+
150
+
151
+ これに合わせてMainViewModelとMainWindow.xamlも以下のように変更します。
152
+
153
+ ```cs
154
+
155
+ public class MainWindowViewModel : BindableBase
156
+
157
+ {
158
+
159
+ // TreeViewへバインディングするXmlDocument
160
+
161
+ public ObservableCollection<PersonViewModel> PeopleTree { get; private set; }
162
+
163
+
164
+
165
+ // コンテキスト
166
+
167
+ public MainWindowViewModel()
168
+
169
+ {
170
+
171
+ using (var fs = new FileStream(@"peopleTree.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
172
+
173
+ {
174
+
175
+ var people = new XmlSerializer(typeof(people)).Deserialize(fs) as people;
176
+
177
+ PeopleTree = new ObservableCollection<PersonViewModel>(people.person.Select(x => new PersonViewModel { Name = x.Name }));
178
+
179
+ }
180
+
181
+ }
182
+
183
+
184
+
185
+ // ボタンへバインディングしているコマンド
186
+
187
+ private ICommand addPersonCommand;
188
+
189
+ public ICommand AddPersonCommand
190
+
191
+ {
192
+
193
+ get { return addPersonCommand ?? (addPersonCommand = new DelegateCommand(addPersonMethod)); }
194
+
195
+ }
196
+
197
+ // ツリーの子ノードとして「名無しさん」を追加する
198
+
199
+ private void addPersonMethod()
200
+
201
+ {
202
+
203
+ PeopleTree.Add(new PersonViewModel { Name = "名無しさん", });
204
+
205
+ }
206
+
207
+ }
208
+
209
+ ```
210
+
211
+ ```xml
212
+
213
+ <HierarchicalDataTemplate
214
+
215
+ x:Key="XmlTemplate"
216
+
217
+ DataType="{x:Type local:PersonViewModel}"
218
+
219
+ ItemsSource="{Binding Child}">
220
+
221
+ <StackPanel>
222
+
223
+ <TextBlock Name="nameTextBlock" Text="{Binding Name}" />
224
+
225
+ </StackPanel>
226
+
227
+ </HierarchicalDataTemplate>
228
+
229
+ ```
230
+
231
+
232
+
233
+ これでボタンをクリックすれば"名無しさん"が追加されます。