回答編集履歴

1

見直しキャンペーン中

2023/07/23 04:06

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -1,507 +1,253 @@
1
1
  VBがわからな過ぎて時間がかかってしまったのですが、一通り作ってみました。
2
-
3
2
  **注意**
4
-
5
3
  面倒なのでボタンなんかは全部コードビハインドです^^;
6
-
7
4
  筋悪(主に`Implements IEnumerable(Of TreeNode)`)なところもありますが、ほかにスマートな方法が思いつきませんでした。
8
-
9
5
  一応動いていますが何かとんでもない間違いがあるかもしれません。
10
6
 
11
-
12
-
13
-
14
-
15
- ```xaml
7
+ ```xml
16
-
17
8
  <Window
18
-
19
9
  x:Class="MainWindow"
20
-
21
10
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
22
-
23
11
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
24
-
25
12
  Width="800"
26
-
27
13
  Height="450">
28
-
29
14
  <DockPanel>
30
-
31
15
  <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
32
-
33
- <Button
16
+ <Button
34
-
35
- Margin="5"
17
+ Margin="5"
36
-
37
18
  Click="AllCheckButton_Click"
38
-
39
19
  Content="全チェック" />
40
-
41
- <Button
20
+ <Button
42
-
43
- Margin="5"
21
+ Margin="5"
44
-
45
22
  Click="AllUncheckButton_Click"
46
-
47
23
  Content="全アンチェック" />
48
-
49
- <Button
24
+ <Button
50
-
51
- Margin="5"
25
+ Margin="5"
52
-
53
26
  Click="AllExpandButton_Click"
54
-
55
27
  Content="全展開" />
56
-
57
- <Button
28
+ <Button
58
-
59
- Margin="5"
29
+ Margin="5"
60
-
61
30
  Click="AllContractButton_Click"
62
-
63
31
  Content="全畳む" />
64
-
65
- <Button
32
+ <Button
66
-
67
- Margin="5"
33
+ Margin="5"
68
-
69
34
  Click="AddNodeButton_Click"
70
-
71
35
  Content="ノード追加" />
72
-
73
36
  </StackPanel>
74
-
75
37
  <TreeView x:Name="treeView" ItemsSource="{Binding Root.Children}">
76
-
77
38
  <TreeView.ItemTemplate>
78
-
79
39
  <HierarchicalDataTemplate ItemsSource="{Binding Children}">
80
-
81
40
  <StackPanel Orientation="Horizontal">
82
-
83
41
  <CheckBox
84
-
85
42
  Margin="5"
86
-
87
43
  VerticalContentAlignment="Center"
88
-
89
44
  IsChecked="{Binding IsChecked}" />
90
-
91
45
  <TextBlock Margin="5" Text="{Binding Name}" />
92
-
93
46
  <Button
94
-
95
47
  Margin="5"
96
-
97
48
  Click="ShowDetailButton_Click"
98
-
99
49
  Content="確認" />
100
-
101
50
  <Button
102
-
103
51
  Margin="5"
104
-
105
52
  Click="DeleteNodeButton_Click"
106
-
107
53
  Content="削除" />
108
-
109
54
  </StackPanel>
110
-
111
55
  </HierarchicalDataTemplate>
112
-
113
56
  </TreeView.ItemTemplate>
114
-
115
57
  <TreeView.ItemContainerStyle>
116
-
117
58
  <Style TargetType="{x:Type TreeViewItem}">
118
-
119
59
  <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
120
-
121
60
  <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
122
-
123
61
  </Style>
124
-
125
62
  </TreeView.ItemContainerStyle>
126
-
127
63
  </TreeView>
128
-
129
64
  </DockPanel>
130
-
131
65
  </Window>
132
-
133
66
  ```
134
67
 
135
-
136
-
137
- ```VB
68
+ ```vb
138
-
139
69
  Imports System.Collections.ObjectModel
140
-
141
70
  Imports System.ComponentModel
142
-
143
71
  Imports System.Runtime.CompilerServices
144
72
 
145
-
146
-
147
73
  Class MainWindow
148
-
149
74
  Private ReadOnly vm As ViewModel
150
75
 
151
-
152
-
153
76
  Public Sub New()
154
-
155
77
  InitializeComponent()
156
-
157
78
  vm = New ViewModel
158
-
159
79
  DataContext = vm
160
-
161
- End Sub
80
+ End Sub
162
-
163
-
164
81
 
165
82
  Private Sub AllCheckButton_Click(sender As Object, e As RoutedEventArgs)
166
-
167
- For Each node As TreeNode In AllNodes(vm.Root)
83
+ For Each node As TreeNode In AllNodes(vm.Root)
168
-
169
84
  node.IsChecked = True
170
-
171
- Next
85
+ Next
172
-
173
- End Sub
86
+ End Sub
174
-
175
-
176
87
 
177
88
  Private Sub AllUncheckButton_Click(sender As Object, e As RoutedEventArgs)
178
-
179
- For Each node As TreeNode In AllNodes(vm.Root)
89
+ For Each node As TreeNode In AllNodes(vm.Root)
180
-
181
90
  node.IsChecked = False
182
-
183
- Next
91
+ Next
184
-
185
- End Sub
92
+ End Sub
186
-
187
-
188
93
 
189
94
  Private Sub AllExpandButton_Click(sender As Object, e As RoutedEventArgs)
190
-
191
- For Each node As TreeNode In AllNodes(vm.Root)
95
+ For Each node As TreeNode In AllNodes(vm.Root)
192
-
193
96
  node.IsExpanded = True
194
-
195
- Next
97
+ Next
196
-
197
- End Sub
98
+ End Sub
198
-
199
-
200
99
 
201
100
  Private Sub AllContractButton_Click(sender As Object, e As RoutedEventArgs)
202
-
203
- For Each node As TreeNode In AllNodes(vm.Root)
101
+ For Each node As TreeNode In AllNodes(vm.Root)
204
-
205
102
  node.IsExpanded = False
206
-
207
- Next
103
+ Next
208
-
209
- End Sub
104
+ End Sub
210
-
211
-
212
105
 
213
106
  Private Sub ShowDetailButton_Click(sender As Object, e As RoutedEventArgs)
214
-
215
107
  Dim button = CType(sender, Button)
216
-
217
108
  Dim node = CType(button.DataContext, TreeNode)
218
109
 
219
-
220
-
221
110
  MessageBox.Show($"Name:{node.Name}{vbCrLf}IsSelected:{node.IsSelected}{vbCrLf}IsExpanded:{node.IsExpanded}{vbCrLf}IsChecked:{node.IsChecked}")
222
-
223
- End Sub
111
+ End Sub
224
-
225
-
226
112
 
227
113
  Private Sub DeleteNodeButton_Click(sender As Object, e As RoutedEventArgs)
228
-
229
114
  Dim button = CType(sender, Button)
230
-
231
115
  Dim node = CType(button.DataContext, TreeNode)
232
116
 
233
-
234
-
235
117
  node.Parent.Remove(node)
236
-
237
- End Sub
118
+ End Sub
238
-
239
-
240
119
 
241
120
  Private Sub AddNodeButton_Click(sender As Object, e As RoutedEventArgs)
242
-
243
121
  Dim node = TryCast(treeView.SelectedItem, TreeNode)
244
-
245
122
  If node Is Nothing Then
246
-
247
123
  vm.Root.Add(New TreeNode("NewNode"))
248
-
249
124
  Else
250
-
251
125
  node.Add(New TreeNode("NewNode"))
252
-
253
126
  End If
254
-
255
- End Sub
127
+ End Sub
256
-
257
-
258
128
 
259
129
  '子孫を全列挙
260
-
261
130
  Private Function AllNodes(node As TreeNode) As IEnumerable(Of TreeNode)
262
-
263
131
  If node Is Nothing Then
264
-
265
132
  Return Enumerable.Empty(Of TreeNode)
266
-
267
133
  End If
268
-
269
134
  Return node.Concat(node.SelectMany(Function(x) AllNodes(x)))
270
-
271
135
  End Function
272
-
273
- End Class
136
+ End Class
274
-
275
-
276
137
 
277
138
  Class ViewModel
278
-
279
139
  Public Property Root As TreeNode 'Rootは表示せず子供から表示(追加・削除の簡便さのため)
280
140
 
281
-
282
-
283
141
  Public Sub New()
284
-
285
142
  Root = New TreeNode("Root") From {
286
-
287
143
  New TreeNode("Node1") From {
288
-
289
144
  New TreeNode("Node1-1"),
290
-
291
145
  New TreeNode("Node1-2") From {
292
-
293
146
  New TreeNode("Node1-2-1"),
294
-
295
147
  New TreeNode("Node1-2-2")
296
-
297
148
  }
298
-
299
149
  },
300
-
301
150
  New TreeNode("Node2") From {
302
-
303
151
  New TreeNode("Node2-1") From {
304
-
305
152
  New TreeNode("Node2-1-1"),
306
-
307
153
  New TreeNode("Node2-1-2")
308
-
309
154
  }
310
-
311
155
  }
312
-
313
156
  }
314
-
315
- End Sub
157
+ End Sub
316
-
317
- End Class
158
+ End Class
318
-
319
-
320
-
321
159
 
322
160
 
323
161
  Public Class TreeNode
324
-
325
162
  Inherits Observable 'INotifyPropertyChangedのベース実装
326
-
327
163
  Implements IEnumerable(Of TreeNode) 'コレクション初期化子を使いたいので
328
164
 
329
-
330
-
331
165
  Public Property Name As String
332
-
333
- Get
166
+ Get
334
-
335
167
  Return _Name
336
-
337
- End Get
168
+ End Get
338
-
339
169
  Set(value As String)
340
-
341
170
  [Set](_Name, value)
342
-
343
- End Set
171
+ End Set
344
-
345
- End Property
172
+ End Property
346
-
347
173
  Private _Name As String
348
174
 
349
-
350
-
351
175
  Public ReadOnly Property Children As ObservableCollection(Of TreeNode) = New ObservableCollection(Of TreeNode)
352
176
 
353
-
354
-
355
177
  Public Property IsSelected As Boolean
356
-
357
- Get
178
+ Get
358
-
359
179
  Return _IsSelected
360
-
361
- End Get
180
+ End Get
362
-
363
181
  Set(value As Boolean)
364
-
365
182
  [Set](_IsSelected, value)
366
-
367
- End Set
183
+ End Set
368
-
369
- End Property
184
+ End Property
370
-
371
185
  Private _IsSelected As Boolean
372
186
 
373
-
374
-
375
187
  Public Property IsExpanded As Boolean
376
-
377
- Get
188
+ Get
378
-
379
189
  Return _IsExpanded
380
-
381
- End Get
190
+ End Get
382
-
383
191
  Set(value As Boolean)
384
-
385
192
  [Set](_IsExpanded, value)
386
-
387
- End Set
193
+ End Set
388
-
389
- End Property
194
+ End Property
390
-
391
195
  Private _IsExpanded As Boolean
392
196
 
393
-
394
-
395
197
  Public Property IsChecked As Boolean
396
-
397
- Get
198
+ Get
398
-
399
199
  Return _IsChecked
400
-
401
- End Get
200
+ End Get
402
-
403
201
  Set(value As Boolean)
404
-
405
202
  [Set](_IsChecked, value)
406
-
407
- End Set
203
+ End Set
408
-
409
- End Property
204
+ End Property
410
-
411
205
  Private _IsChecked As Boolean
412
206
 
413
207
 
414
-
415
-
416
-
417
208
  Friend Parent As TreeNode '追加・削除の簡便さのため親ノードが欲しい
418
209
 
419
210
 
420
-
421
-
422
-
423
211
  Sub New(name As String)
424
-
425
212
  _Name = name
426
-
427
- End Sub
213
+ End Sub
428
-
429
-
430
214
 
431
215
  Public Sub Add(child As TreeNode)
432
-
433
216
  child.Parent = Me
434
-
435
217
  Children.Add(child)
436
-
437
- End Sub
218
+ End Sub
438
-
439
-
440
219
 
441
220
  Public Sub Remove(child As TreeNode)
442
-
443
221
  Children.Remove(child)
444
-
445
222
  child.Parent = Nothing
446
-
447
- End Sub
223
+ End Sub
448
-
449
-
450
224
 
451
225
  #Region "IEnumerable"
452
-
453
226
  Public Function GetEnumerator() As IEnumerator(Of TreeNode) Implements IEnumerable(Of TreeNode).GetEnumerator
454
-
455
227
  Return Children.GetEnumerator()
456
-
457
228
  End Function
458
229
 
459
-
460
-
461
230
  Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
462
-
463
231
  Return GetEnumerator()
464
-
465
232
  End Function
466
-
467
233
  #End Region
468
-
469
- End Class
234
+ End Class
470
-
471
-
472
-
473
235
 
474
236
 
475
237
  'INotifyPropertyChanged 定番実装
476
-
477
238
  'https://github.com/microsoft/WindowsTemplateStudio/blob/dev/templates/Uwp/_comp/MVVMBasic/Project._VB/Helpers/Observable.vb
478
-
479
239
  Public Class Observable
480
-
481
240
  Implements INotifyPropertyChanged
482
-
483
241
  Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
484
-
485
242
  Friend Sub [Set](Of T)(ByRef storage As T, newValue As T, <CallerMemberName> Optional propertyName As String = Nothing)
486
-
487
243
  If Equals(storage, newValue) Then
488
-
489
244
  Return
490
-
491
245
  End If
492
-
493
246
  storage = newValue
494
-
495
247
  OnPropertyChanged(propertyName)
496
-
497
- End Sub
248
+ End Sub
498
-
499
249
  Protected Sub OnPropertyChanged(propertyName As String)
500
-
501
250
  RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
502
-
503
- End Sub
251
+ End Sub
504
-
505
- End Class
252
+ End Class
506
-
507
253
  ```