Vb.net Сохранить, какие узлы были развернуты в TreeView

Я создаю форму в VB.net, содержащую TreeView. Этот TreeView заполняется расширяемыми родительскими узлами и соответствующими дочерними узлами. Когда пользователь запускает программу, он может расширять любые узлы по своему желанию. Есть ли способ программно сохранить, какие узлы были расширены, чтобы при следующей загрузке формы эти узлы оставались развернутыми? Мне не обязательно нужны закодированные примеры (хотя они могут быть полезны), просто общее представление о командах/элементах управления/логике для использования в программе. Заранее спасибо!


person Aidan Kehoe    schedule 25.05.2016    source источник
comment
Есть несколько способов. MySettings, сохраните в файл, используя двоичный форматтер, базу данных, это зависит от вас, как вы хотите сохранить эти данные и получить их обратно.   -  person zaggler    schedule 25.05.2016
comment
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что он не относится к проблеме программирования, а является рекомендацией.   -  person zaggler    schedule 25.05.2016


Ответы (1)


Вот несколько основных идей, которые помогут вам в реализации:

Создайте список, чтобы отслеживать узлы, которые в настоящее время развернуты:

Private _ExpandedNodeList As New List(Of String)

Настройте два обработчика событий для отслеживания событий AfterCollapse и AfterExpand TreeView — они происходят, когда пользователь открывает/закрывает разные части дерева. Хитрость здесь в том, что обработчики событий просто добавляют и удаляют значение тега узла, которое представляет собой некоторую строку, которую вы установили для узла при построении дерева.

Private Sub TreeView_AfterCollapse(sender As Object, e As TreeViewEventArgs) Handles TreeView.AfterCollapse
    If _ExpandedNodeList.Contains(e.Node.Tag.ToString) Then
        _ExpandedNodeList.Remove(e.Node.Tag.ToString)
    End If
End Sub
Private Sub TreeView_AfterExpand(sender As Object, e As TreeViewEventArgs) Handles TreeView.AfterExpand
    If Not _ExpandedNodeList.Contains(e.Node.Tag.ToString) Then
        _ExpandedNodeList.Add(e.Node.Tag.ToString)
    End If
End Sub

Теперь давайте предположим, что у вас есть точка в приложении, где вам нужно восстановить TreeView до определенного состояния. Вы можете рекурсивно использовать узлы в TreeView и вызывать Expand для тех, которые есть в вашем списке.

Моя реализация выглядит так:

Private Sub ShowVisibleNodes()
    Dim Node As TreeNode

    For Each ExpandedChildNodeName As String In _ExpandedNodeList
        For Each RootNode As TreeNode In TreeView.Nodes
            Node = NodeFromTagName(ExpandedChildNodeName, RootNode)
            If Node IsNot Nothing Then
                Node.Expand()
            End If
        Next
    Next

End Sub
Private Function NodeFromTagName(ByVal NodeTagName As String, NodeToSearch As TreeNode) As TreeNode
    Dim NextNode As TreeNode

    'check input node
    If NodeToSearch.Tag IsNot Nothing Then
        If NodeToSearch.Tag.Equals(NodeTagName) Then
            Return NodeToSearch
        End If
    End If

    'check child nodes and recurse on intermediary nodes
    For Each Node As TreeNode In NodeToSearch.Nodes
        If Node.Tag IsNot Nothing Then
            If Node.Tag.Equals(NodeTagName) Then
                Return Node
            End If
            NextNode = NodeFromTagName(NodeTagName, Node)
            If NextNode IsNot Nothing Then
                Return NextNode
            End If
        End If
    Next

    Return Nothing

End Function

Обратите внимание, что этот код не гарантирует работу, если просто добавить его в приложение.

По крайней мере, вам нужно тщательно подумать о построении вашего дерева и о том, устанавливаете ли вы значение тега для каждого узла дерева.

Надеюсь, это поможет вам начать.

person Robin Mackenzie    schedule 25.05.2016
comment
Вау это здорово спасибо! И когда я создам свой ExpandedNodesList, будет ли он сохранен и будет доступен при следующем запуске приложения пользователем? - person Aidan Kehoe; 25.05.2016
comment
Вы определенно можете сохранить список, но вы должны сделать это самостоятельно. Например, когда приложение закрывается, вы можете записать его в текстовый файл. Или загляните в пространство имен System.Runtime.Serialization. - person Robin Mackenzie; 25.05.2016
comment
Я предполагаю, что отрицательный результат здесь связан с тем, что я не интерпретировал «сохранить» как «сохранить в файл», а интерпретировал «сохранить» как «хранить где-то в безопасности»? Да здравствует педантичность, ха! - person Robin Mackenzie; 25.05.2016
comment
Хорошо, отлично, я подумал, что это должно быть записано в текстовый файл. (кстати, у меня недостаточно репутации, чтобы голосовать). Кто бы ни проголосовал, поделитесь, пожалуйста, причиной, по которой ответ не является исчерпывающим, мне было бы интересно узнать, не пропустил ли я что-то. - person Aidan Kehoe; 25.05.2016
comment
@Robin просто выдавать что-то неконструктивно, когда у ОП явно нет ничего, что могло бы показать нам, что они пытались сделать. Мы не одобряем простое написание кода для них, а помогаем в конкретных вопросах. Если люди будут продолжать это делать, это может стать проблемой, поскольку мы не являемся службой написания кода. I don't necessarily need coded examples (although they can be useful), just a general idea of the commands/controls/logic to use in the program Имея это в виду, достаточно небольшого комментария, так как это даст ему пищу для размышлений. - person zaggler; 25.05.2016
comment
@AidanKehoe причина отрицательного голосования в том, что это не должно быть ответом, ответ явно не объясняет, как сохранять расширенные узлы вообще или перезагружать их при загрузке , но вы принимаете ответ, который явно не соответствует поставленному вопросу. Как принятое решение решает вашу проблему? Также вы не знали, с чего начать, с учетом этого вы понимаете принятое решение? I figured it would have to be written to a text file Я упомянул об этом в своем комментарии выше, почему вы не задали больше вопросов, это было недостаточно полезно, с чего начать? - person zaggler; 25.05.2016
comment
@zaggler спасибо за объяснение вашего отрицательного голоса. Пара комментариев - в вопросе нет речи о закрытии приложения, сериализации настроек, перезапуске приложения, восстановлении настроек из файла и т.д. Он мог загружать и выгружать Form во время выполнения и нужно восстанавливать из списка пока приложение, в целом , до сих пор работает. У меня есть приложение, которое делает что-то очень похожее и делится фрагментами с ОП, чтобы помочь ему. Я заметил, что он не может просто бросить код в своем приложении, поэтому не верьте, что его кормят с ложечки (и это не его просьба). - person Robin Mackenzie; 25.05.2016
comment
Is there a way to programmatically save which nodes were expanded so that next time the form is loaded, those nodes remain expanded? Кажется, он спросил об этом. Вы упомянули there's no talk about closing the application, serializing settings, restarting the application, restoring settings from file etc, я просто не согласен с тем, что он явно это сделал. - person zaggler; 25.05.2016
comment
@zaggler Спасибо за ваш комментарий. Я принял ответ, потому что он помог мне с моим текущим проектом. Я могу использовать рекурсивный метод проверки узлов, чтобы найти узлы из списка для расширения (после изменений, конечно). Хотя в ответе она явно не указала, как сохранить узлы для перезагрузки, она подтвердила мою идею распечатать их в текстовый файл и загрузить в следующий раз. В результате полный ответ (т.е. включая комментарии) может быть использован для решения моей проблемы... продолжение... - person Aidan Kehoe; 25.05.2016
comment
... имейте в виду, я не просил полного решения (и она мне его не дала). Что касается того, понял ли я решение, то ответ прост: понял. Текущая версия проекта использует не древовидное представление, а представление списка. Я просто пытаюсь перейти от одного к другому и искал несколько советов. Я посчитал, что прикрепление всего моего проекта будет бесполезным, так как в этом нет ничего плохого, я просто пытаюсь улучшить небольшой раздел. Я не понимаю, как любое из моих действий может заставить вас поверить, что я не понимаю ответа Робин. - person Aidan Kehoe; 25.05.2016