質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

1695閲覧

WPFでのTreeViewへデータバインディング2

Hayashi_Jelly

総合スコア26

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

0クリップ

投稿2020/08/14 08:01

編集2023/07/23 13:06

分からないこと

コードが長く申し訳ありませんが、TreeViewの描画についてです。

TreeViewを描画するのみであれば、実現できたのですが(QAその1)、
最終的に、TreeView上の要素を取得したり、ビューからビューモデルの変更をしたかったり
(TreeView上にチェックボックスを表示させ、チェック状態を変更可能にする)
と、要件の実現を考えていく中で、TreeViewItemレベルでモデルを作る方法がネットに載っており、
参考にした方法
それが何をしたいのか、自分でも理解しやすかったため、参考にしました。

要素の取得などする以前に、表示したい文字列RealNameをバインディングすることができていません。
QAその1で、描画のみしたときは、HierarchicalDataTemplateを使ったせいか、モデルのプロパティで描画できたのですが、
この場合は、どうすればいいのかが分かりません。

VB

1Imports System.ComponentModel 2'------------------------------------------------------------------------- 3' モデルのモデル 4Public Class TreeViewOrigin 5 Private Property _RealName As String 6 Public Property RealName As String 7 Get 8 Return _RealName 9 End Get 10 Set(value As String) 11 _RealName = value 12 End Set 13 End Property 14 15 Private _Children As List(Of TreeViewOrigin) 16 Public Property Children As List(Of TreeViewOrigin) 17 Get 18 Return _Children 19 End Get 20 Set(value As List(Of TreeViewOrigin)) 21 _Children = value 22 End Set 23 End Property 24End Class 25 26'------------------------------------------------------------------------- 27' モデル 28Public Class TreeViewModel2 : Inherits TreeViewItem 29 30 Private _Expand As Boolean 31 32 Private __Origin As TreeViewOrigin 33 Private Property _Origin As TreeViewOrigin 34 Get 35 Return __Origin 36 End Get 37 Set(value As TreeViewOrigin) 38 __Origin = value 39 End Set 40 End Property 41 42 43 Private _RealName As String 44 Public Property RealName As String 45 Get 46 Return Me._RealName 47 End Get 48 Set(value As String) 49 Me._RealName = value 50 End Set 51 End Property 52 53 54 Private _SelectItem As TreeViewModel2 55 Public Property SelectItem As TreeViewModel2 56 Get 57 Return _SelectItem 58 End Get 59 Set(value As TreeViewModel2) 60 _SelectItem = value 61 End Set 62 End Property 63 64 65 '展開時に子要素をすべてインスタンス化 66 Private Sub _ExpandedBehavior(ByVal sender As Object, ByVal e As RoutedEventArgs) 67 If Not Me._Expand Then 68 Me.Items.Clear() 69 For Each c In Me._Origin.Children 70 Me.Items.Add(New TreeViewModel2(c)) 71 Next 72 Me._Expand = True 73 End If 74 End Sub 75 76 77 Private Sub _SelectedBehavior(ByVal sender As Object, ByVal e As RoutedEventArgs) 78 If Me.IsSelected Then 79 Me.SelectItem = Me 80 Else 81 Me.SelectItem = e.Source 82 End If 83 End Sub 84 85 86 Sub New(ByRef tvo As TreeViewOrigin) 87 Me._Expand = False 88 89 Me._Origin = tvo 90 Me.RealName = tvo.RealName 91 92 If tvo.Children IsNot Nothing Then 93 '空のアイテムを追加しておくことで、展開の>が表示される 94 Me.Items.Add(New TreeViewItem()) 95 AddHandler Me.Expanded, AddressOf Me._ExpandedBehavior 96 End If 97 98 AddHandler Me.Selected, AddressOf Me._SelectedBehavior 99 End Sub 100End Class 101 102'------------------------------------------------------------------------- 103' ビューモデル 104Public Class TreeViewViewModel 105 Inherits ViewModel 106 107 108 Private _Model As List(Of TreeViewModel2) 109 Public Property Model As List(Of TreeViewModel2) 110 Get 111 Return _Model 112 End Get 113 Set(value As List(Of TreeViewModel2)) 114 _Model = value 115 End Set 116 End Property 117 118 119 Sub New(ByRef tvm As TreeViewModel2) 120 Me.Model = New List(Of TreeViewModel2) 121 Me.Model.Add(tvm) 122 End Sub 123End Class 124 125'------------------------------------------------------------------------- 126' ビュー 127Public Class MainWin 128 Public Sub New() 129 130 ' この呼び出しはデザイナーで必要です。 131 InitializeComponent() 132 133 ' InitializeComponent() 呼び出しの後で初期化を追加します。 134 135 Dim tvo As New TreeViewOrigin With { 136 .RealName = "hoge", 137 .Children = New List(Of TreeViewOrigin) From { 138 New TreeViewOrigin With { 139 .RealName = "fuga", 140 .Children = New List(Of TreeViewOrigin) From { 141 New TreeViewOrigin With {.RealName = "piyo"} 142 } 143 } 144 } 145 } 146 Dim tvm As New TreeViewModel2(tvo) 147 148 Dim tvvm As New TreeViewViewModel(tvm) 149 Me.TreeView.DataContext = tvvm 150 End Sub 151End Class 152 153

XAML

1<Window x:Class="MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApplication1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="350" Width="525"> 9 <Grid> 10 : 11 (省略) 12 : 13 <TreeView x:Name="TreeView" 14 ItemsSource="{Binding Path=Model}" 15 Grid.ColumnSpan="20" Grid.Column="0" 16 HorizontalAlignment="Stretch" 17 Grid.Row="0" Grid.RowSpan="50" 18 VerticalAlignment="Stretch"> 19 <TreeView.ItemTemplate> 20 <DataTemplate> 21 <TextBlock Text="{Binding Path=RealName}" /> 22 </DataTemplate> 23 </TreeView.ItemTemplate> 24 </TreeView> 25 </Grid> 26</Window>
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2020/08/14 09:21

かえって難しくしているように感じます。 > TreeViewItemレベルでモデルを作る方法がネットに載っており よければurlを追記してください。 チェックボックスが必要ならViewModelにbool値を用意してバインドします。 ExpandやSelectも同様です。 前回の参考urlは難しかったですかね?(遅延取得していてわかりにくかったかも) VBでの記事があまりないのと、私も全然わからないのでわかりやすい例が出せずもどかしいですね。。
Hayashi_Jelly

2020/08/15 08:46

すみません。前回の質問では、答えて頂いたコードで、その時の自分の問題点が解決してしまったので、URLは拝見していませんでした。 先程、流し見ですが拝見させて頂いたところ、コードのやりたいこと(概要)は自分が参考にしたのものと似たような感じなのですが、こちらは、ViewModelにバインドさせたいプロパティを持たせられているので、こちらを参考に実装してみたいと思います。
TN8001

2020/08/15 08:49

参考urlありがとうございます。 なるほど。。ざっとしか見ていませんが「MVVM的に作る」ってのには違和感しかないですね。 TreeViewItemがModelってのはさすがに無理があると思います。 フォルダ表示専用のTreeViewのカスタムコントロールってほうがしっくりきます。
guest

回答1

0

ベストアンサー

VBがわからな過ぎて時間がかかってしまったのですが、一通り作ってみました。
注意
面倒なのでボタンなんかは全部コードビハインドです^^;
筋悪(主にImplements IEnumerable(Of TreeNode))なところもありますが、ほかにスマートな方法が思いつきませんでした。
一応動いていますが何かとんでもない間違いがあるかもしれません。

xml

1<Window 2 x:Class="MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <DockPanel> 8 <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> 9 <Button 10 Margin="5" 11 Click="AllCheckButton_Click" 12 Content="全チェック" /> 13 <Button 14 Margin="5" 15 Click="AllUncheckButton_Click" 16 Content="全アンチェック" /> 17 <Button 18 Margin="5" 19 Click="AllExpandButton_Click" 20 Content="全展開" /> 21 <Button 22 Margin="5" 23 Click="AllContractButton_Click" 24 Content="全畳む" /> 25 <Button 26 Margin="5" 27 Click="AddNodeButton_Click" 28 Content="ノード追加" /> 29 </StackPanel> 30 <TreeView x:Name="treeView" ItemsSource="{Binding Root.Children}"> 31 <TreeView.ItemTemplate> 32 <HierarchicalDataTemplate ItemsSource="{Binding Children}"> 33 <StackPanel Orientation="Horizontal"> 34 <CheckBox 35 Margin="5" 36 VerticalContentAlignment="Center" 37 IsChecked="{Binding IsChecked}" /> 38 <TextBlock Margin="5" Text="{Binding Name}" /> 39 <Button 40 Margin="5" 41 Click="ShowDetailButton_Click" 42 Content="確認" /> 43 <Button 44 Margin="5" 45 Click="DeleteNodeButton_Click" 46 Content="削除" /> 47 </StackPanel> 48 </HierarchicalDataTemplate> 49 </TreeView.ItemTemplate> 50 <TreeView.ItemContainerStyle> 51 <Style TargetType="{x:Type TreeViewItem}"> 52 <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 53 <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> 54 </Style> 55 </TreeView.ItemContainerStyle> 56 </TreeView> 57 </DockPanel> 58</Window>

vb

1Imports System.Collections.ObjectModel 2Imports System.ComponentModel 3Imports System.Runtime.CompilerServices 4 5Class MainWindow 6 Private ReadOnly vm As ViewModel 7 8 Public Sub New() 9 InitializeComponent() 10 vm = New ViewModel 11 DataContext = vm 12 End Sub 13 14 Private Sub AllCheckButton_Click(sender As Object, e As RoutedEventArgs) 15 For Each node As TreeNode In AllNodes(vm.Root) 16 node.IsChecked = True 17 Next 18 End Sub 19 20 Private Sub AllUncheckButton_Click(sender As Object, e As RoutedEventArgs) 21 For Each node As TreeNode In AllNodes(vm.Root) 22 node.IsChecked = False 23 Next 24 End Sub 25 26 Private Sub AllExpandButton_Click(sender As Object, e As RoutedEventArgs) 27 For Each node As TreeNode In AllNodes(vm.Root) 28 node.IsExpanded = True 29 Next 30 End Sub 31 32 Private Sub AllContractButton_Click(sender As Object, e As RoutedEventArgs) 33 For Each node As TreeNode In AllNodes(vm.Root) 34 node.IsExpanded = False 35 Next 36 End Sub 37 38 Private Sub ShowDetailButton_Click(sender As Object, e As RoutedEventArgs) 39 Dim button = CType(sender, Button) 40 Dim node = CType(button.DataContext, TreeNode) 41 42 MessageBox.Show($"Name:{node.Name}{vbCrLf}IsSelected:{node.IsSelected}{vbCrLf}IsExpanded:{node.IsExpanded}{vbCrLf}IsChecked:{node.IsChecked}") 43 End Sub 44 45 Private Sub DeleteNodeButton_Click(sender As Object, e As RoutedEventArgs) 46 Dim button = CType(sender, Button) 47 Dim node = CType(button.DataContext, TreeNode) 48 49 node.Parent.Remove(node) 50 End Sub 51 52 Private Sub AddNodeButton_Click(sender As Object, e As RoutedEventArgs) 53 Dim node = TryCast(treeView.SelectedItem, TreeNode) 54 If node Is Nothing Then 55 vm.Root.Add(New TreeNode("NewNode")) 56 Else 57 node.Add(New TreeNode("NewNode")) 58 End If 59 End Sub 60 61 '子孫を全列挙 62 Private Function AllNodes(node As TreeNode) As IEnumerable(Of TreeNode) 63 If node Is Nothing Then 64 Return Enumerable.Empty(Of TreeNode) 65 End If 66 Return node.Concat(node.SelectMany(Function(x) AllNodes(x))) 67 End Function 68End Class 69 70Class ViewModel 71 Public Property Root As TreeNode 'Rootは表示せず子供から表示(追加・削除の簡便さのため) 72 73 Public Sub New() 74 Root = New TreeNode("Root") From { 75 New TreeNode("Node1") From { 76 New TreeNode("Node1-1"), 77 New TreeNode("Node1-2") From { 78 New TreeNode("Node1-2-1"), 79 New TreeNode("Node1-2-2") 80 } 81 }, 82 New TreeNode("Node2") From { 83 New TreeNode("Node2-1") From { 84 New TreeNode("Node2-1-1"), 85 New TreeNode("Node2-1-2") 86 } 87 } 88 } 89 End Sub 90End Class 91 92 93Public Class TreeNode 94 Inherits Observable 'INotifyPropertyChangedのベース実装 95 Implements IEnumerable(Of TreeNode) 'コレクション初期化子を使いたいので 96 97 Public Property Name As String 98 Get 99 Return _Name 100 End Get 101 Set(value As String) 102 [Set](_Name, value) 103 End Set 104 End Property 105 Private _Name As String 106 107 Public ReadOnly Property Children As ObservableCollection(Of TreeNode) = New ObservableCollection(Of TreeNode) 108 109 Public Property IsSelected As Boolean 110 Get 111 Return _IsSelected 112 End Get 113 Set(value As Boolean) 114 [Set](_IsSelected, value) 115 End Set 116 End Property 117 Private _IsSelected As Boolean 118 119 Public Property IsExpanded As Boolean 120 Get 121 Return _IsExpanded 122 End Get 123 Set(value As Boolean) 124 [Set](_IsExpanded, value) 125 End Set 126 End Property 127 Private _IsExpanded As Boolean 128 129 Public Property IsChecked As Boolean 130 Get 131 Return _IsChecked 132 End Get 133 Set(value As Boolean) 134 [Set](_IsChecked, value) 135 End Set 136 End Property 137 Private _IsChecked As Boolean 138 139 140 Friend Parent As TreeNode '追加・削除の簡便さのため親ノードが欲しい 141 142 143 Sub New(name As String) 144 _Name = name 145 End Sub 146 147 Public Sub Add(child As TreeNode) 148 child.Parent = Me 149 Children.Add(child) 150 End Sub 151 152 Public Sub Remove(child As TreeNode) 153 Children.Remove(child) 154 child.Parent = Nothing 155 End Sub 156 157#Region "IEnumerable" 158 Public Function GetEnumerator() As IEnumerator(Of TreeNode) Implements IEnumerable(Of TreeNode).GetEnumerator 159 Return Children.GetEnumerator() 160 End Function 161 162 Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator 163 Return GetEnumerator() 164 End Function 165#End Region 166End Class 167 168 169'INotifyPropertyChanged 定番実装 170'https://github.com/microsoft/WindowsTemplateStudio/blob/dev/templates/Uwp/_comp/MVVMBasic/Project._VB/Helpers/Observable.vb 171Public Class Observable 172 Implements INotifyPropertyChanged 173 Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 174 Friend Sub [Set](Of T)(ByRef storage As T, newValue As T, <CallerMemberName> Optional propertyName As String = Nothing) 175 If Equals(storage, newValue) Then 176 Return 177 End If 178 storage = newValue 179 OnPropertyChanged(propertyName) 180 End Sub 181 Protected Sub OnPropertyChanged(propertyName As String) 182 RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) 183 End Sub 184End Class

投稿2020/08/15 08:50

編集2023/07/23 04:06
TN8001

総合スコア9244

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hayashi_Jelly

2020/08/19 08:56

ありがとうございました。xamlが分からないとダメですね。 コレクションの初期化のところのとか、すごい参考になりました。 (これで入れ子構造になるのか・・・)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問