Desenvolvimento - C#
Persistindo TreeView no Banco de Dados
O intuito deste artigo é mostrar uma das maneiras possíveis de salvarmos os dados de uma TreeView no Banco de Dados para que a mesma possa ser carregada em um momento posterior.
por André Alves de Lima1. Introdução
O intuito deste artigo é mostrar uma das maneiras possíveis de salvarmos os dados de uma TreeView no Banco de Dados para que a mesma possa ser carregada em um momento posterior.
Existem vários métodos para atender essa demanda, como utilizar-se de serialização, utilizar o componente DBTreeControl ou criar uma estrutura própria para armazenar os nós do Banco de Dados, sendo essa última a que será abordada neste artigo.
2. Representando a TreeView em um Banco de Dados Relacional
Para entendermos como podemos armazenar uma TreeView no Banco de Dados, tomemos a seguinte TreeView representada na figura abaixo como exemplo.
Como vocês podem observar, a seção “Mail Folders” do Outlook conta com uma TreeView para organizar a nossa lista de pastas. Toda TreeView tem uma ou mais raízes (no nosso exemplo, o nó “Personal Folders”) e nós filhos, como “Deleted Items”, “Faculdade”, “Raptors”, etc. Um detalhe importante da TreeView é que, para qualquer nó não raíz, nós sempre conseguimos identificar qual é o nó pai do mesmo.
Portanto, uma das estruturas de tabela de Banco de Dados que podem ser utilizadas para armazenar os nós de uma TreeView é a seguinte:
A coluna CodNode é utilizada como identificador do nó, a coluna CodParentNode contará com o identificador do nó que é seu pai e a coluna Description conterá uma breve descrição do nó, que será exibida na nossa TreeView de exemplo.
Dessa forma, a TreeView do Outlook que exibimos anteriormente poderia ser armazenada da seguinte forma nessa tabela:
3. Criando a aplicação para salvar a TreeView
Com o Visual Studio 2008 ou 2010, criaremos uma aplicação Windows Forms utilizando o .Net Framework 3.5.
Após o projeto ter sido criado, localize o componente da TreeView na toolbox e arraste-a para o form criado pelo Visual Studio. Dê o nome de treeViewSample para essa TreeView. Inclua também quatro Buttons (btAddNode, btRemoveNode, btSaveTreeView e btLoadTreeView) e um TextBox (tbNode) nesse form, de forma que ele fique parecido com a figura abaixo:
Feito isso, iniciemos implementando os métodos de inclusão e exclusão de nós. Para tanto, no evento click do botão de “Adicionar Nó”, utilize o seguinte código:
private void btAddNode_Click(object sender, EventArgs e)
{
if (!tbNode.Text.Equals(string.Empty))
{
TreeNode newNode = new TreeNode(tbNode.Text);
if (treeViewSample.SelectedNode != null)
treeViewSample.SelectedNode.Nodes.Add(newNode);
else
treeViewSample.Nodes.Add(newNode);
if (newNode.Parent != null)
newNode.Parent.Expand();
treeViewSample.SelectedNode = null;
}
else
MessageBox.Show("Por favor, digite um texto para o novo nó!!!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Já para o botão de “Remover Nó”, utilize o código:
private void btRemoveNode_Click(object sender, EventArgs e)
{
if (treeViewSample.SelectedNode != null)
treeViewSample.Nodes.Remove(treeViewSample.SelectedNode);
}
Para a parte de acesso a dados, utilizaremos nesse exemplo o Linq to Sql. Portanto, adicione um novo item do tipo LINQ to SQL Classes à sua solução, dando o nome de TreeViewDB.
Na janela de edição do dbml, escolha a opção Server Explorer e adicione a conexão apontanto para o Banco de Dados onde está armazenada a tabela que persistirá a TreeView.
Uma vez encontrada a tabela na aba Server Explorer, arraste-a para dentro do dbml, para que o Visual Studio crie as classes de persistência, conforme ilustrado na figura abaixo.
Altere o nome da Parent Property to auto-relacionamento para um nome mais amigável (utilizei o nome ParentNode), conforme ilustrado na figura abaixo:
Feito isso, o Visual Studio já terá criado todas as classes necessárias para fazermos a persistência de dados dessa tabela.
Portanto, voltemos ao nosso form para adicionarmos um atributo com o DataContext dessa tabela:
private TreeViewDBDataContext db = new TreeViewDBDataContext();
O próximo passo é implementar o código do nosso botão que salva a TreeView no Banco. Para tanto, utilize o seguinte código:
private void btSaveTreeView_Click(object sender, EventArgs e)
{
db.NodesTables.DeleteAllOnSubmit(db.NodesTables);
db.SubmitChanges();
foreach (TreeNode node in treeViewSample.Nodes)
{
NodesTable newDBNode = new NodesTable() { Description = node.Text };
SaveChildren(node, ref newDBNode);
db.NodesTables.InsertOnSubmit(newDBNode);
}
db.SubmitChanges();
}
private void SaveChildren(TreeNode treeNode, ref NodesTable dbNode)
{
foreach (TreeNode node in treeNode.Nodes)
{
NodesTable childDBNode = new NodesTable()
{
Description = node.Text,
ParentNode = dbNode
};
SaveChildren(node, ref childDBNode);
}
}
O código acima limpa a tabela NodesTable (com a chamada DeleteAllOnSubmit) e, recursivamente, percorre o componente treeViewSample criando os registros para representar a TreeView na nossa tabela de NodesTable no Banco de Dados.
A única parte que fica faltando é o código para carregar a TreeView do Banco de Dados, que é apresentado logo abaixo:
private void btLoadTreeView_Click(object sender, EventArgs e)
{
treeViewSample.Nodes.Clear();
var rootNodes = from n in db.NodesTables
where n.CodParentNode == null
select n;
foreach (NodesTable rootNode in rootNodes)
{
TreeNode newNode = new TreeNode(rootNode.Description);
LoadChildren(ref newNode, rootNode.ChildrenNodes);
treeViewSample.Nodes.Add(newNode);
}
treeViewSample.ExpandAll();
}
private void LoadChildren(ref TreeNode treeNode, System.Data.Linq.EntitySet<NodesTable> childrenNodes)
{
foreach (NodesTable childNode in childrenNodes)
{
TreeNode newNode = new TreeNode(childNode.Description);
LoadChildren(ref newNode, childNode.ChildrenNodes);
treeNode.Nodes.Add(newNode);
}
}
Com os códigos acima, você conseguirá salvar a estrutura da TreeView na tabela NodesTable e posteriormente carregar a mesma do Banco de Dados.
4. Conclusão
Como explicado na introdução deste artigo, esse é um dos métodos que poderiam ser utilizados para salvar a estrutura da TreeView no Banco de Dados.
Em futuros artigos, apresentarei outras formas de obtermos o mesmo resultado utilizando outros métodos de persistência.
Vamos ficando por aqui. Espero que tenham gostado. Qualquer dúvida é só entrar em contato! Até a próxima!