組織単位リスト画面の Web アプリの VB のコードです。
'直下のオブジェクト格納用(OU自身のパス, 直下のオブジェクトの名前と種類と説明を格納したデータソース用のテーブル)
Private domainObjectsInfos As Dictionary(Of String, DataTable)
Private ouCol As List(Of OrganizationalUnit) 'OUのコレクション
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If MyBase.Page.IsPostBack Then 'ポストバックの時
domainObjectsInfos = DirectCast(ViewState("domainObjectsInfos"), Dictionary(Of String, DataTable))
Return
End If
Dim ous = DirectoryAccess.GetOrganizationalUnits() 'OUを取得
ouCol = ous.OrderBy(Function(ou) ou.DisplayPath).ThenBy(Function(ou) ou.Name).ToList()
Me.CountLabel.Text = String.Format("{0} 個のオブジェクト", ous.Count)
domainObjectsInfos = New Dictionary(Of String, DataTable)()
ViewState("domainObjectsInfos") = domainObjectsInfos
Me.AddChildNode(Nothing) '子ノードを追加
End Sub
Private Sub DetailDataSource_Selecting(
sender As Object, e As ObjectDataSourceSelectingEventArgs) Handles DetailDataSource.Selecting
If Me.OUTreeView.SelectedNode Is Nothing Then
e.Cancel = True
End If
End Sub
Private Sub DetailDataSource_Selected(
sender As Object, e As ObjectDataSourceStatusEventArgs) Handles DetailDataSource.Selected
Me.DataPanel.Visible = True
Me.ShowStoredData(DirectCast(e.ReturnValue, OrganizationalUnit)) '格納されているデータを表示
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Response.Redirect("Main.aspx?idx=3")
End Sub
'子ノードを追加
Private Sub AddChildNode(node As TreeNode)
Dim path = If(node Is Nothing, String.Empty, node.ValuePath)
Dim childOUs = ouCol.Where(Function(ou) ou.DisplayPath.Equals(path)).ToList() '直下のOU
For Each ou In childOUs
Dim childNode = CreateNode(ou) 'ノードを作成
If node Is Nothing Then
Me.OUTreeView.Nodes.Add(childNode)
Else
node.Nodes.Add(childNode)
End If
Me.AddChildNode(childNode) '子ノードを追加
Next
End Sub
'指定した OU のノードを作成
Private Function CreateNode(ou As OrganizationalUnit) As TreeNode
Dim path = If(ou.DisplayPath.Length = 0, String.Empty, ou.DisplayPath & "/")
Return New TreeNode(ou.Name, path & ou.Name)
End Function
'指定した OU に格納されているデータを表示
Private Sub ShowStoredData(ou As OrganizationalUnit)
Dim table As DataTable = Nothing
If domainObjectsInfos.TryGetValue(Me.OUTreeView.SelectedValue, table) = False Then '直下のオブジェクトを格納していない時
table = CreateDataSourceTable() 'データソース用のテーブルを作成
For Each domainObject In ou.StoredDomainObjects '直下のオブジェクト数分
Dim row = table.NewRow()
Dim objectType = DirectCast([Enum].Parse(GetType(CategoryType), domainObject.Entry.SchemaClassName, True), CategoryType)
row.Item(0) = domainObject.Name '名前をセット
row.Item(1) = DirectoryAccess.CategoryNames.Item(objectType) '種類をセット
row.Item(2) = domainObject.Description '説明をセット
table.Rows.Add(row)
Next
domainObjectsInfos.Add(Me.OUTreeView.SelectedValue, table)
End If
Me.DataCountLabel.Text = String.Format("{0} 個のオブジェクト", table.Rows.Count)
Me.DataCountLabel.Visible = table.Rows.Count > 0
Me.DataGridView.DataSource = table
Me.DataGridView.DataBind()
End Sub
'データソース用のテーブルを作成
Private Function CreateDataSourceTable() As DataTable
Dim table As New DataTable()
table.Columns.Add(New DataColumn("Name", GetType(String)))
table.Columns.Add(New DataColumn("Type", GetType(String)))
table.Columns.Add(New DataColumn("Description", GetType(String)))
Return table
End Function
選択した OU は、格納しているオブジェクトの情報を DataTable に格納して Dictionary に追加してます。
その Dictionary を ViewState に保持してて、ポストバック時は ViewState から Dictionary を復元してます。
Dictionary のキーは OU 自身のパスで、これは TreeView のノードの値です。
選択したことのある OU は Dictionary から DataTable を取り出してます。
TreeView のノードを作る部分は Windows アプリとほとんど同じです。