Results 1 to 6 of 6

Thread: Populate TreeView Across Forms Issues

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    May 2012
    Posts
    248

    Question Populate TreeView Across Forms Issues

    Hi there,

    The issue I'm about to explain doesn't occur when I have copied my code into a new project to test, and also if I create new forms and module to test it on in my existing project.

    I apologise now if my code is messy and doesn't conform to best practices, if anyone has any suggestions on improving it it would be appreciated.

    I have a Form 'frm_DocumentListCP' which has a TreeView 'tvw_CustomView', right clicking the TreeView opens a Context Menu which allows you to 'add a view' (which will add to database and display as a TreeView Node. Selecting 'add a view' opens a form 'frm_CustomView'.

    From here you can enter a name for the view and click 'OK' to add it to the database. This works fine, it is the Sub that runs after that that doesn't seem to work. I want it to re-populate the TreeView showing the newly added view.

    Module: mod_GlobalSubs:
    vb Code:
    1. Public CustomView_JobNo As String = Nothing
    2.     Public DataViewCustomViewsTree As DataView


    Module: mod_GlobalVariables:
    vb Code:
    1. Public Sub TreeReadCustomViews(ByVal tvw As TreeView, ByVal JobNo As String)
    2.         tvw.Nodes.Clear()
    3.  
    4.         Dim DatabaseConnection As SqlConnection = New SqlConnection(DataSource & "Job_" & JobNo & ";")
    5.         Dim SQL As String = "SELECT [View Name], [Path] " & _
    6.                             "FROM Custom_Views " & _
    7.                             "WHERE [User] = '" & CurrentUser & "' " & _
    8.                             "OR [User] IS NULL " & _
    9.                             "ORDER BY [Path] ASC"
    10.  
    11.         Dim DataAdapter As New SqlDataAdapter(SQL, DatabaseConnection)
    12.         Dim DataTableCustomViews As New DataTable("Custom Views")
    13.  
    14.         Try
    15.             DatabaseConnection.Open()
    16.             DataAdapter.Fill(DataTableCustomViews)
    17.         Catch ex As SqlException
    18.             MessageBox.Show(ex.ToString)
    19.         Finally
    20.             DatabaseConnection.Close()
    21.             DatabaseConnection.Dispose()
    22.         End Try
    23.  
    24.         DataViewCustomViewsTree = New DataView(DataTableCustomViews)
    25.         'DataViewCustomViewsTree.RowFilter = "[Category = DC Level 4] = '" & Category & "'"
    26.         FillTreeCustomViews(tvw, DataViewCustomViewsTree)
    27.  
    28.         'prepareTreeViewDocs(Me.tvw_CustomView)
    29.     End Sub
    30.  
    31.     Public Sub FillTreeCustomViews(ByVal tvw As TreeView, ByVal dv As DataView)
    32.         'ProfileTimer.TheTime.Track("e")
    33.         tvw.Nodes.Clear()
    34.  
    35.         For Each dr As DataRowView In dv
    36.             Dim Path As String = dr(0).ToString & "\" & dr(1).ToString
    37.             Dim PathString() As String = Split(Path, "\")
    38.             Dim lNode(Split(Path, "\").Length - 1) As TreeNode, i As Integer, lKey As String, lNodeCol As TreeNodeCollection
    39.  
    40.             lKey = vbNullString
    41.             For i = 0 To Split(Path, "\").Length - 1
    42.                 lKey = lKey & PathString(i)
    43.                 If i = 0 Then lNodeCol = tvw.Nodes Else lNodeCol = lNode(i - 1).Nodes
    44.                 If Not lNodeCol.ContainsKey(lKey) Then
    45.                     lNode(i) = lNodeCol.Add(lKey, PathString(i))
    46.                 Else
    47.                     lNode(i) = lNodeCol.Item(lNodeCol.IndexOfKey(lKey))
    48.                 End If
    49.             Next
    50.         Next
    51.         'setTreeViewIcons(Me.tvw_CustomView)
    52.         For Each n As TreeNode In tvw.Nodes
    53.             If n.Level = 0 Then
    54.                 n.NodeFont = New Font(tvw.Font, FontStyle.Bold)
    55.                 n.Text = n.Text & " "
    56.             End If
    57.         Next
    58.     End Sub


    Form: frm_DocumentListCP:
    vb Code:
    1. Private Sub tvw_CustomView_NodeMouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles tvw_CustomView.NodeMouseClick
    2.         If e.Button = MouseButtons.Right Then
    3.             tvw_CustomView.SelectedNode = e.Node
    4.         End If
    5.     End Sub
    6.  
    7.     Private Sub tmi_CreateView_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmi_CreateView.Click
    8.         CustomView_JobNo = DocumentListCP_ProjectID_Local
    9.         frm_CustomView.ShowDialog()
    10.     End Sub


    Form: frm_CustomView:
    vb Code:
    1. Imports System.Data.SqlClient
    2.  
    3. Public Class frm_CustomView
    4.  
    5.     Private Sub btn_OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_OK.Click
    6.         If rdb_AllUsers.Checked = False And rdb_CurrentUser.Checked = False Then
    7.             MessageBox.Show("Please select an option.", "Create View", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    8.             Exit Sub
    9.         Else
    10.             If tbx_ViewName.Text = "" Then
    11.                 MessageBox.Show("Please enter a name.", "Create View", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    12.                 Exit Sub
    13.             Else
    14.                 addCustomView(CustomView_JobNo)
    15.                 TreeReadCustomViews(frm_DocumentListCP.tvw_CustomView, CustomView_JobNo)
    16.                 Me.Close()
    17.             End If
    18.         End If
    19.     End Sub
    20.  
    21.     Private Sub btn_Cancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Cancel.Click
    22.         Me.Close()
    23.     End Sub
    24.  
    25.     Private Sub addCustomView(ByVal JobNo As String)
    26.         'Connects to database and checks if generated document number exists
    27.         Dim DatabaseConnection As SqlConnection = New SqlConnection(DataSource & "Job_" & JobNo & ";")
    28.         Dim DatabaseCommand As SqlCommand = New SqlCommand("INSERT INTO Custom_Views (" & _
    29.                                                             "[View Name], " & _
    30.                                                             "[User]) " & _
    31.                                                             "VALUES (@ViewName, @User)", DatabaseConnection)
    32.         DatabaseCommand.Parameters.AddWithValue("@ViewName", CType(tbx_ViewName.Text, String))
    33.         If rdb_AllUsers.Checked = True Then
    34.             DatabaseCommand.Parameters.AddWithValue("@User", DBNull.Value)
    35.         Else
    36.             DatabaseCommand.Parameters.AddWithValue("@User", CType(CurrentUser, String))
    37.         End If
    38.  
    39.         Try
    40.             DatabaseConnection.Open()
    41.             DatabaseCommand.ExecuteNonQuery()
    42.         Catch ex As SqlException
    43.             MessageBox.Show(Me, ex.ToString, "Error:")
    44.         Finally
    45.             DatabaseCommand.Dispose()
    46.             DatabaseConnection.Close()
    47.             DatabaseConnection.Dispose()
    48.         End Try
    49.     End Sub
    50. End Class


    The TreeViews and DataGridViews in frm_DocumentListCP are originally populated with the following Sub:
    vb Code:
    1. Private Sub refreshLists(ByVal JobNo As String)
    2.         RemoveHandler tvw_Documents.AfterCollapse, AddressOf tvw_Documents_AfterCollapse
    3.         RemoveHandler tvw_Documents.AfterExpand, AddressOf tvw_Documents_AfterExpand
    4.         RemoveHandler tvw_DocumentsBulk.AfterCollapse, AddressOf tvw_DocumentsBulk_AfterCollapse
    5.         RemoveHandler tvw_DocumentsBulk.AfterExpand, AddressOf tvw_DocumentsBulk_AfterExpand
    6.         'RemoveHandler tvw_Documents.AfterSelect, AddressOf tvw_Documents_AfterSelect
    7.         'MsgBox(Me.tvw_Documents.SelectedNode.Text)
    8.         Dim RefreshLoadType As String
    9.         Dim StoredGridFilter As String
    10.  
    11.         If CurrentGridFilter = Nothing Then
    12.             RefreshLoadType = "Load"
    13.         Else
    14.             StoredGridFilter = CurrentGridFilter
    15.         End If
    16.         'MsgBox("1")
    17.         treeReadDocs(JobNo, DocumentListCP_Category_Local)
    18.         treeReadBulk(JobNo, DocumentListCP_Category_Local)
    19.         TreeReadCustomViews(Me.tvw_CustomView, JobNo)
    20.         'MsgBox("2")
    21.         fillDataGridDocs(JobNo)
    22.  
    23.         If RefreshLoadType <> "Load" Then
    24.             'MsgBox(StoredGridFilter)
    25.             DataViewDocs.RowFilter = StoredGridFilter
    26.             PrepareColumnsDocuments(Me.dgv_Documents, DocumentListCP_ProjectID_Local, True)
    27.         Else
    28.             'MsgBox("3")
    29.             dataFilterDocs()
    30.         End If
    31.  
    32.         UsedNodes.Sort(Function(x, y) x.Level.CompareTo(y.Level))
    33.         For Each n As TreeNode In UsedNodes
    34.             'MsgBox(n.Name.ToString)
    35.             'n.Expand()
    36.             Try
    37.                 tvw_Documents.Nodes.Find(n.Name, True)(0).Expand()
    38.             Catch ex As Exception
    39.  
    40.             End Try
    41.         Next
    42.  
    43.         UsedNodesBulk.Sort(Function(x, y) x.Level.CompareTo(y.Level))
    44.         For Each n As TreeNode In UsedNodesBulk
    45.             'MsgBox(n.Name.ToString)
    46.             'n.Expand()
    47.             Try
    48.                 tvw_DocumentsBulk.Nodes.Find(n.Name, True)(0).Expand()
    49.             Catch ex As Exception
    50.  
    51.             End Try
    52.         Next
    53.  
    54.         frm_Transmittal.dgv_TMDocuments.Columns.Clear()
    55.         frm_RFI.dgv_RFIDocuments.Columns.Clear()
    56.         frm_Notification.dgv_NotificationDocuments.Columns.Clear()
    57.         frm_Transmittal.dgv_TMDocuments.Rows.Clear()
    58.         frm_RFI.dgv_RFIDocuments.Rows.Clear()
    59.         frm_Notification.dgv_NotificationDocuments.Rows.Clear()
    60.         'SelectedCategory(DocumentListCP_Category_Local)
    61.  
    62.         'AddHandler tvw_Documents.AfterSelect, AddressOf tvw_Documents_AfterSelect
    63.         AddHandler tvw_DocumentsBulk.AfterExpand, AddressOf tvw_DocumentsBulk_AfterExpand
    64.         AddHandler tvw_DocumentsBulk.AfterCollapse, AddressOf tvw_DocumentsBulk_AfterCollapse
    65.         AddHandler tvw_Documents.AfterExpand, AddressOf tvw_Documents_AfterExpand
    66.         AddHandler tvw_Documents.AfterCollapse, AddressOf tvw_Documents_AfterCollapse
    67.     End Sub

    Thanks for your time, any help would be appreciated.

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    105,461

    Re: Populate TreeView Across Forms Issues

    Quote Originally Posted by squatman View Post
    I want it to re-populate the TreeView showing the newly added view.
    Is there really a good reason to do that? If the only thing that's changing is one new node is being added then why don't you just add that node? Why do you have to go back to the database just to get a whole lot of data that you already have?

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    May 2012
    Posts
    248

    Re: Populate TreeView Across Forms Issues

    jmcilhinney, thank you for your response.

    This is a very late reply from me, so apologies for that.

    I guess I hadn't thought that I could just add a node, because the ones there already where from a database.

    Also, there is usually multiple users/machines looking at the same information, so if a new node is added, I'd want everyone to be able to see it. So not sure if that changes anything in your suggestion?

    Thank you.

  4. #4
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    105,461

    Re: Populate TreeView Across Forms Issues

    There are two main problems with doing a total data refresh like that. Firstly, it's slower than a partial update. This may not be a big deal for small amounts of data but it can be a problem for larger data sets. Secondly, it can play havoc with the UI, e.g. a TreeView that was expanded in a particular way will be reset to its default state.

    If you have control of the database, it's generally preferable to use time stamps to allow you to perform partial updates. That means that you can never delete a record but rather include a column that indicates whether a record has been logically deleted and also include a column that indicates when the record was last modified.

    That allows you to query the database at any time for records that have been modified since the last time you checked. That will be a small subset of the total data and it will include those records that have been logically deleted. You can then simply add, edit or remove only those nodes in your TreeView that have changed. That means that the expansion state of the tree will not change and the user's selection will also not change.

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    May 2012
    Posts
    248

    Re: Populate TreeView Across Forms Issues

    jmc, thank you again for your time and response.

    I'm always keen to know better practices for accomplishing a task, so thank you for that.

    Regarding the above, say a user adds a record to the Database, this is also added to the TreeView (and actually a DataGridView), for all the other clients accessing the same information, would it be acceptable having a timer checking every **seconds for data added after a certain datetime and then add this into their TreeView/DataGridView..?

    Hope that makes sense.

    Thanks again.

  6. #6
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    105,461

    Re: Populate TreeView Across Forms Issues

    Quote Originally Posted by squatman View Post
    would it be acceptable having a timer checking every **seconds for data added after a certain datetime and then add this into their TreeView/DataGridView..?
    Absolutely. That's not an uncommon scenario.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width