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

回答編集履歴

1

見直しキャンペーン中

2023/07/23 04:06

投稿

TN8001
TN8001

スコア10263

answer CHANGED
@@ -1,254 +1,253 @@
1
- VBがわからな過ぎて時間がかかってしまったのですが、一通り作ってみました。
2
- **注意**
3
- 面倒なのでボタンなんかは全部コードビハインドです^^;
4
- 筋悪(主に`Implements IEnumerable(Of TreeNode)`)なところもありますが、ほかにスマートな方法が思いつきませんでした。
5
- 一応動いていますが何かとんでもない間違いがあるかもしれません。
6
-
7
-
8
- ```xaml
9
- <Window
10
- x:Class="MainWindow"
11
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
12
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
13
- Width="800"
14
- Height="450">
15
- <DockPanel>
16
- <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
17
- <Button
18
- Margin="5"
19
- Click="AllCheckButton_Click"
20
- Content="全チェック" />
21
- <Button
22
- Margin="5"
23
- Click="AllUncheckButton_Click"
24
- Content="全アンチェック" />
25
- <Button
26
- Margin="5"
27
- Click="AllExpandButton_Click"
28
- Content="全展開" />
29
- <Button
30
- Margin="5"
31
- Click="AllContractButton_Click"
32
- Content="全畳む" />
33
- <Button
34
- Margin="5"
35
- Click="AddNodeButton_Click"
36
- Content="ノード追加" />
37
- </StackPanel>
38
- <TreeView x:Name="treeView" ItemsSource="{Binding Root.Children}">
39
- <TreeView.ItemTemplate>
40
- <HierarchicalDataTemplate ItemsSource="{Binding Children}">
41
- <StackPanel Orientation="Horizontal">
42
- <CheckBox
43
- Margin="5"
44
- VerticalContentAlignment="Center"
45
- IsChecked="{Binding IsChecked}" />
46
- <TextBlock Margin="5" Text="{Binding Name}" />
47
- <Button
48
- Margin="5"
49
- Click="ShowDetailButton_Click"
50
- Content="確認" />
51
- <Button
52
- Margin="5"
53
- Click="DeleteNodeButton_Click"
54
- Content="削除" />
55
- </StackPanel>
56
- </HierarchicalDataTemplate>
57
- </TreeView.ItemTemplate>
58
- <TreeView.ItemContainerStyle>
59
- <Style TargetType="{x:Type TreeViewItem}">
60
- <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
61
- <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
62
- </Style>
63
- </TreeView.ItemContainerStyle>
64
- </TreeView>
65
- </DockPanel>
66
- </Window>
67
- ```
68
-
69
- ```VB
70
- Imports System.Collections.ObjectModel
71
- Imports System.ComponentModel
72
- Imports System.Runtime.CompilerServices
73
-
74
- Class MainWindow
75
- Private ReadOnly vm As ViewModel
76
-
77
- Public Sub New()
78
- InitializeComponent()
79
- vm = New ViewModel
80
- DataContext = vm
81
- End Sub
82
-
83
- Private Sub AllCheckButton_Click(sender As Object, e As RoutedEventArgs)
84
- For Each node As TreeNode In AllNodes(vm.Root)
85
- node.IsChecked = True
86
- Next
87
- End Sub
88
-
89
- Private Sub AllUncheckButton_Click(sender As Object, e As RoutedEventArgs)
90
- For Each node As TreeNode In AllNodes(vm.Root)
91
- node.IsChecked = False
92
- Next
93
- End Sub
94
-
95
- Private Sub AllExpandButton_Click(sender As Object, e As RoutedEventArgs)
96
- For Each node As TreeNode In AllNodes(vm.Root)
97
- node.IsExpanded = True
98
- Next
99
- End Sub
100
-
101
- Private Sub AllContractButton_Click(sender As Object, e As RoutedEventArgs)
102
- For Each node As TreeNode In AllNodes(vm.Root)
103
- node.IsExpanded = False
104
- Next
105
- End Sub
106
-
107
- Private Sub ShowDetailButton_Click(sender As Object, e As RoutedEventArgs)
108
- Dim button = CType(sender, Button)
109
- Dim node = CType(button.DataContext, TreeNode)
110
-
111
- MessageBox.Show($"Name:{node.Name}{vbCrLf}IsSelected:{node.IsSelected}{vbCrLf}IsExpanded:{node.IsExpanded}{vbCrLf}IsChecked:{node.IsChecked}")
112
- End Sub
113
-
114
- Private Sub DeleteNodeButton_Click(sender As Object, e As RoutedEventArgs)
115
- Dim button = CType(sender, Button)
116
- Dim node = CType(button.DataContext, TreeNode)
117
-
118
- node.Parent.Remove(node)
119
- End Sub
120
-
121
- Private Sub AddNodeButton_Click(sender As Object, e As RoutedEventArgs)
122
- Dim node = TryCast(treeView.SelectedItem, TreeNode)
123
- If node Is Nothing Then
124
- vm.Root.Add(New TreeNode("NewNode"))
125
- Else
126
- node.Add(New TreeNode("NewNode"))
127
- End If
128
- End Sub
129
-
130
- '子孫を全列挙
131
- Private Function AllNodes(node As TreeNode) As IEnumerable(Of TreeNode)
132
- If node Is Nothing Then
133
- Return Enumerable.Empty(Of TreeNode)
134
- End If
135
- Return node.Concat(node.SelectMany(Function(x) AllNodes(x)))
136
- End Function
137
- End Class
138
-
139
- Class ViewModel
140
- Public Property Root As TreeNode 'Rootは表示せず子供から表示(追加・削除の簡便さのため)
141
-
142
- Public Sub New()
143
- Root = New TreeNode("Root") From {
144
- New TreeNode("Node1") From {
145
- New TreeNode("Node1-1"),
146
- New TreeNode("Node1-2") From {
147
- New TreeNode("Node1-2-1"),
148
- New TreeNode("Node1-2-2")
149
- }
150
- },
151
- New TreeNode("Node2") From {
152
- New TreeNode("Node2-1") From {
153
- New TreeNode("Node2-1-1"),
154
- New TreeNode("Node2-1-2")
155
- }
156
- }
157
- }
158
- End Sub
159
- End Class
160
-
161
-
162
- Public Class TreeNode
163
- Inherits Observable 'INotifyPropertyChangedベース実装
164
- Implements IEnumerable(Of TreeNode) 'コレクション初期化子を使いたいので
165
-
166
- Public Property Name As String
167
- Get
168
- Return _Name
169
- End Get
170
- Set(value As String)
171
- [Set](_Name, value)
172
- End Set
173
- End Property
174
- Private _Name As String
175
-
176
- Public ReadOnly Property Children As ObservableCollection(Of TreeNode) = New ObservableCollection(Of TreeNode)
177
-
178
- Public Property IsSelected As Boolean
179
- Get
180
- Return _IsSelected
181
- End Get
182
- Set(value As Boolean)
183
- [Set](_IsSelected, value)
184
- End Set
185
- End Property
186
- Private _IsSelected As Boolean
187
-
188
- Public Property IsExpanded As Boolean
189
- Get
190
- Return _IsExpanded
191
- End Get
192
- Set(value As Boolean)
193
- [Set](_IsExpanded, value)
194
- End Set
195
- End Property
196
- Private _IsExpanded As Boolean
197
-
198
- Public Property IsChecked As Boolean
199
- Get
200
- Return _IsChecked
201
- End Get
202
- Set(value As Boolean)
203
- [Set](_IsChecked, value)
204
- End Set
205
- End Property
206
- Private _IsChecked As Boolean
207
-
208
-
209
- Friend Parent As TreeNode '追加・削除の簡便さのため親ノードが欲しい
210
-
211
-
212
- Sub New(name As String)
213
- _Name = name
214
- End Sub
215
-
216
- Public Sub Add(child As TreeNode)
217
- child.Parent = Me
218
- Children.Add(child)
219
- End Sub
220
-
221
- Public Sub Remove(child As TreeNode)
222
- Children.Remove(child)
223
- child.Parent = Nothing
224
- End Sub
225
-
226
- #Region "IEnumerable"
227
- Public Function GetEnumerator() As IEnumerator(Of TreeNode) Implements IEnumerable(Of TreeNode).GetEnumerator
228
- Return Children.GetEnumerator()
229
- End Function
230
-
231
- Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
232
- Return GetEnumerator()
233
- End Function
234
- #End Region
235
- End Class
236
-
237
-
238
- 'INotifyPropertyChanged 定番実装
239
- 'https://github.com/microsoft/WindowsTemplateStudio/blob/dev/templates/Uwp/_comp/MVVMBasic/Project._VB/Helpers/Observable.vb
240
- Public Class Observable
241
- Implements INotifyPropertyChanged
242
- Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
243
- Friend Sub [Set](Of T)(ByRef storage As T, newValue As T, <CallerMemberName> Optional propertyName As String = Nothing)
244
- If Equals(storage, newValue) Then
245
- Return
246
- End If
247
- storage = newValue
248
- OnPropertyChanged(propertyName)
249
- End Sub
250
- Protected Sub OnPropertyChanged(propertyName As String)
251
- RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
252
- End Sub
253
- End Class
1
+ VBがわからな過ぎて時間がかかってしまったのですが、一通り作ってみました。
2
+ **注意**
3
+ 面倒なのでボタンなんかは全部コードビハインドです^^;
4
+ 筋悪(主に`Implements IEnumerable(Of TreeNode)`)なところもありますが、ほかにスマートな方法が思いつきませんでした。
5
+ 一応動いていますが何かとんでもない間違いがあるかもしれません。
6
+
7
+ ```xml
8
+ <Window
9
+ x:Class="MainWindow"
10
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
11
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
12
+ Width="800"
13
+ Height="450">
14
+ <DockPanel>
15
+ <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
16
+ <Button
17
+ Margin="5"
18
+ Click="AllCheckButton_Click"
19
+ Content="全チェック" />
20
+ <Button
21
+ Margin="5"
22
+ Click="AllUncheckButton_Click"
23
+ Content="全アンチェック" />
24
+ <Button
25
+ Margin="5"
26
+ Click="AllExpandButton_Click"
27
+ Content="全展開" />
28
+ <Button
29
+ Margin="5"
30
+ Click="AllContractButton_Click"
31
+ Content="全畳む" />
32
+ <Button
33
+ Margin="5"
34
+ Click="AddNodeButton_Click"
35
+ Content="ノード追加" />
36
+ </StackPanel>
37
+ <TreeView x:Name="treeView" ItemsSource="{Binding Root.Children}">
38
+ <TreeView.ItemTemplate>
39
+ <HierarchicalDataTemplate ItemsSource="{Binding Children}">
40
+ <StackPanel Orientation="Horizontal">
41
+ <CheckBox
42
+ Margin="5"
43
+ VerticalContentAlignment="Center"
44
+ IsChecked="{Binding IsChecked}" />
45
+ <TextBlock Margin="5" Text="{Binding Name}" />
46
+ <Button
47
+ Margin="5"
48
+ Click="ShowDetailButton_Click"
49
+ Content="確認" />
50
+ <Button
51
+ Margin="5"
52
+ Click="DeleteNodeButton_Click"
53
+ Content="削除" />
54
+ </StackPanel>
55
+ </HierarchicalDataTemplate>
56
+ </TreeView.ItemTemplate>
57
+ <TreeView.ItemContainerStyle>
58
+ <Style TargetType="{x:Type TreeViewItem}">
59
+ <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
60
+ <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
61
+ </Style>
62
+ </TreeView.ItemContainerStyle>
63
+ </TreeView>
64
+ </DockPanel>
65
+ </Window>
66
+ ```
67
+
68
+ ```vb
69
+ Imports System.Collections.ObjectModel
70
+ Imports System.ComponentModel
71
+ Imports System.Runtime.CompilerServices
72
+
73
+ Class MainWindow
74
+ Private ReadOnly vm As ViewModel
75
+
76
+ Public Sub New()
77
+ InitializeComponent()
78
+ vm = New ViewModel
79
+ DataContext = vm
80
+ End Sub
81
+
82
+ Private Sub AllCheckButton_Click(sender As Object, e As RoutedEventArgs)
83
+ For Each node As TreeNode In AllNodes(vm.Root)
84
+ node.IsChecked = True
85
+ Next
86
+ End Sub
87
+
88
+ Private Sub AllUncheckButton_Click(sender As Object, e As RoutedEventArgs)
89
+ For Each node As TreeNode In AllNodes(vm.Root)
90
+ node.IsChecked = False
91
+ Next
92
+ End Sub
93
+
94
+ Private Sub AllExpandButton_Click(sender As Object, e As RoutedEventArgs)
95
+ For Each node As TreeNode In AllNodes(vm.Root)
96
+ node.IsExpanded = True
97
+ Next
98
+ End Sub
99
+
100
+ Private Sub AllContractButton_Click(sender As Object, e As RoutedEventArgs)
101
+ For Each node As TreeNode In AllNodes(vm.Root)
102
+ node.IsExpanded = False
103
+ Next
104
+ End Sub
105
+
106
+ Private Sub ShowDetailButton_Click(sender As Object, e As RoutedEventArgs)
107
+ Dim button = CType(sender, Button)
108
+ Dim node = CType(button.DataContext, TreeNode)
109
+
110
+ MessageBox.Show($"Name:{node.Name}{vbCrLf}IsSelected:{node.IsSelected}{vbCrLf}IsExpanded:{node.IsExpanded}{vbCrLf}IsChecked:{node.IsChecked}")
111
+ End Sub
112
+
113
+ Private Sub DeleteNodeButton_Click(sender As Object, e As RoutedEventArgs)
114
+ Dim button = CType(sender, Button)
115
+ Dim node = CType(button.DataContext, TreeNode)
116
+
117
+ node.Parent.Remove(node)
118
+ End Sub
119
+
120
+ Private Sub AddNodeButton_Click(sender As Object, e As RoutedEventArgs)
121
+ Dim node = TryCast(treeView.SelectedItem, TreeNode)
122
+ If node Is Nothing Then
123
+ vm.Root.Add(New TreeNode("NewNode"))
124
+ Else
125
+ node.Add(New TreeNode("NewNode"))
126
+ End If
127
+ End Sub
128
+
129
+ '子孫を全列挙
130
+ Private Function AllNodes(node As TreeNode) As IEnumerable(Of TreeNode)
131
+ If node Is Nothing Then
132
+ Return Enumerable.Empty(Of TreeNode)
133
+ End If
134
+ Return node.Concat(node.SelectMany(Function(x) AllNodes(x)))
135
+ End Function
136
+ End Class
137
+
138
+ Class ViewModel
139
+ Public Property Root As TreeNode 'Rootは表示せず子供から表示(追加・削除の簡便さのため)
140
+
141
+ Public Sub New()
142
+ Root = New TreeNode("Root") From {
143
+ New TreeNode("Node1") From {
144
+ New TreeNode("Node1-1"),
145
+ New TreeNode("Node1-2") From {
146
+ New TreeNode("Node1-2-1"),
147
+ New TreeNode("Node1-2-2")
148
+ }
149
+ },
150
+ New TreeNode("Node2") From {
151
+ New TreeNode("Node2-1") From {
152
+ New TreeNode("Node2-1-1"),
153
+ New TreeNode("Node2-1-2")
154
+ }
155
+ }
156
+ }
157
+ End Sub
158
+ End Class
159
+
160
+
161
+ Public Class TreeNode
162
+ Inherits Observable 'INotifyPropertyChangedのベース実装
163
+ Implements IEnumerable(Of TreeNode) 'コレクション初期化子を使いたい
164
+
165
+ Public Property Name As String
166
+ Get
167
+ Return _Name
168
+ End Get
169
+ Set(value As String)
170
+ [Set](_Name, value)
171
+ End Set
172
+ End Property
173
+ Private _Name As String
174
+
175
+ Public ReadOnly Property Children As ObservableCollection(Of TreeNode) = New ObservableCollection(Of TreeNode)
176
+
177
+ Public Property IsSelected As Boolean
178
+ Get
179
+ Return _IsSelected
180
+ End Get
181
+ Set(value As Boolean)
182
+ [Set](_IsSelected, value)
183
+ End Set
184
+ End Property
185
+ Private _IsSelected As Boolean
186
+
187
+ Public Property IsExpanded As Boolean
188
+ Get
189
+ Return _IsExpanded
190
+ End Get
191
+ Set(value As Boolean)
192
+ [Set](_IsExpanded, value)
193
+ End Set
194
+ End Property
195
+ Private _IsExpanded As Boolean
196
+
197
+ Public Property IsChecked As Boolean
198
+ Get
199
+ Return _IsChecked
200
+ End Get
201
+ Set(value As Boolean)
202
+ [Set](_IsChecked, value)
203
+ End Set
204
+ End Property
205
+ Private _IsChecked As Boolean
206
+
207
+
208
+ Friend Parent As TreeNode '追加・削除の簡便さのため親ノードが欲しい
209
+
210
+
211
+ Sub New(name As String)
212
+ _Name = name
213
+ End Sub
214
+
215
+ Public Sub Add(child As TreeNode)
216
+ child.Parent = Me
217
+ Children.Add(child)
218
+ End Sub
219
+
220
+ Public Sub Remove(child As TreeNode)
221
+ Children.Remove(child)
222
+ child.Parent = Nothing
223
+ End Sub
224
+
225
+ #Region "IEnumerable"
226
+ Public Function GetEnumerator() As IEnumerator(Of TreeNode) Implements IEnumerable(Of TreeNode).GetEnumerator
227
+ Return Children.GetEnumerator()
228
+ End Function
229
+
230
+ Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
231
+ Return GetEnumerator()
232
+ End Function
233
+ #End Region
234
+ End Class
235
+
236
+
237
+ 'INotifyPropertyChanged 定番実装
238
+ 'https://github.com/microsoft/WindowsTemplateStudio/blob/dev/templates/Uwp/_comp/MVVMBasic/Project._VB/Helpers/Observable.vb
239
+ Public Class Observable
240
+ Implements INotifyPropertyChanged
241
+ Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
242
+ Friend Sub [Set](Of T)(ByRef storage As T, newValue As T, <CallerMemberName> Optional propertyName As String = Nothing)
243
+ If Equals(storage, newValue) Then
244
+ Return
245
+ End If
246
+ storage = newValue
247
+ OnPropertyChanged(propertyName)
248
+ End Sub
249
+ Protected Sub OnPropertyChanged(propertyName As String)
250
+ RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
251
+ End Sub
252
+ End Class
254
253
  ```