VB.NET : Herança - Criando controles herdados.


 

Um dos maiores benefícios que a orientação a objetos trouxe é a capacidade de estender o comportamento de uma classe existente e continuar a utilizar código escrito para a classe original.

 

Quando você estende uma classe para criar uma nova classe , a nova classe estendida herda todas as propriedades e métodos da classe que foi estendida. A classe original é conhecida como superclasse , classe pai ou classe base ; a classe que estendida é conhecida como classe filha ou subclasse.(Se a classe filha não sobrepõe(overrides) nenhum procedimento da classe pai, ela herda todo o comportamento da classe pai.)

 

Com o poder da herança você pode criar novas classes herdando características de uma classe que já existe ; pode também incluir novas propriedades e métodos e modificar aqueles que foram herdados.

 

Como você já deve saber o  VB.NET é uma linguagem realmente orientada a objetos e suporta herança.

 

Tudo no VB.NET são classes e na própria livraria de classes .NET existem centenas de exemplos de classes que utilizam herança: o controle LinkLabel estende do controle Label e herda seus métodos e propriedades  o controle CheckedListBox estende do controle ListBox .

 

Algumas das características importantes sobre herança no VB.NET são:

Para mais detalhes sobre herança leia os artigos :

Embora o conceito de herança possa ser fácil de entender sua utilização na prática para quem esta acostumado a usar a programação estrutura pode não ser tão simples de assimilar. Colocar em prática e utilizar no dia a dia o conceito de herança requer mudança na mentalidade e na maneira de encarar o problema e propor as soluções. Muitas vezes perde-se tempo reescrevendo uma grande quantidade de código quando a solução já esta pronto requerendo apenas um retoque adicional.

 

Vou mostrar neste artigo como podemos usar a herança para criar controles que herdam propriedades e métodos de controles já existentes estendendo algumas de suas funcionalidades. Meu objetivo é mostrar na prática soluções que usam a herança e que são fáceis de implementar. Vamos lá...

 

Criando um controle com base em um controle já existente usando a herança

 

No artigo  - VB.NET - Criando Controles Personalizados - mostrei como criar controles personalizados do tipo User Control mas não confunda !!! o que eu vou mostrar neste artigo é outra forma de criar controles: estou falando dos controles herdados.

 

Vamos supor que você precise utilizar com frequência em um projeto o recurso de exibir a árvore de diretórios. Você pode fazer isto via código mas existe uma maneira mais inteligente de fazer isto usando herança. Uma delas é criar um controle que faça exatamente isto com base em um controle já existente. Para isto devemos procurar um controle existente que já tenha algumas das funcionalidades que você precisa e criar outro controle que estenda este controle.

 

O controle TreeView possui muitas das funcionalidades que podem ser aplicadas na visualização de itens e é o mais indicado para ser usado como classe base ou classe pai do nosso. Vamos chamar nosso novo controle de DirectoryTree (pensei em ArvoreArquivos mas achei que não ia ficar legal ).

 

Vamos então criar o controle DirectoryTree com base no controle TreeView.

 

1- No projeto onde pretende usar o controle inclua um novo projeto do tipo Class. Clique no menu Project | Add Class e selecione Class informando o nome da classe em seguida :

 

 

2- No módulo de classe vamos usar a declaração imports para System.IO pois vamos fazer acesso a arquivos e diretórios . Declare a classe com o modificar Public e utilize a palavra Inherits treeView para indicar a herança.

 

 

O código completo da classe que irá tornar nosso controle DirectoryTree funcional é o seguinte :

 
Imports System.IO

Public Class DirectoryTree
    Inherits TreeView
    Event DiretorioSelecionado(ByVal sender As Object, ByVal e As DiretorioSelecionadoEventArgs)

    Public Class DiretorioSelecionadoEventArgs
        Inherits EventArgs
        Public nomeDiretorio As String
        Public Sub New(ByVal nomeDiretorio_ As String)
            Me.nomeDiretorio = nomeDiretorio_
        End Sub

    End Class

    Private Drive_ As Char

    Public Property Drive() As Char
        Get
            Return Drive_
        End Get
        Set(ByVal Value As Char)
            Drive_ = Value
            refrescaExibicao()
        End Set
    End Property
    Public Sub refrescaExibicao()
        'limpa a arvore existente
        Me.Nodes.Clear()

        'define o primeiro No
        Dim noRaiz_ As New TreeNode(Drive_ & ":\")
        Me.Nodes.Add(noRaiz_)

        preencheControle(noRaiz_)
        Me.Nodes(0).Expand()
    End Sub

    Private Sub preencheControle(ByVal DirNo As TreeNode)
 
        Dim dir As New DirectoryInfo(DirNo.FullPath)
        Dim dirItem As DirectoryInfo

        For Each dirItem In dir.GetDirectories
            Dim novoNo As New TreeNode(dirItem.Name)
            DirNo.Nodes.Add(novoNo)
            novoNo.Nodes.Add("*")
        Next
 
    End Sub

    Protected Overrides Sub onBeforeExpand(ByVal e As TreeViewCancelEventArgs)
        MyBase.OnBeforeExpand(e)
        If e.Node.Nodes(0).Text = "*" Then
            e.Node.Nodes.Clear()
            preencheControle(e.Node)
        End If
    End Sub

    Protected Overrides Sub OnAfterSelect(ByVal e As TreeViewEventArgs)

        MyBase.OnAfterSelect(e)
        RaiseEvent DiretorioSelecionado(Me, New DiretorioSelecionadoEventArgs(e.Node.FullPath))

    End Sub

End Class

 

 

1- Criamos um novo evento para o nosso controle :

 

 Event DiretorioSelecionado(ByVal sender As Object, ByVal e As DiretorioSelecionadoEventArgs)

 

2- A seguir definimos uma classe que herdar de EventArgs e que trata o evento definido:

 

    Public Class DiretorioSelecionadoEventArgs
        Inherits EventArgs

        Public nomeDiretorio As String
        Public Sub New(ByVal nomeDiretorio_ As String)
            Me.nomeDiretorio = nomeDiretorio_
        End Sub
    End Class

3- Definimos uma propriedade privada Drive_ do tipo Char que irá representar o drive

 

    Private Drive_ As Char

 

4- Como Drive_ é uma propriedade privada implementamos o código abaixo para permitir o acesso a ela de fora da classe.

 

    Public Property Drive() As Char
        Get
            Return Drive_
        End Get
        Set(ByVal Value As Char)
            Drive_ = Value
            refrescaExibicao()
        End Set
    End Property

5-  Implementamos a rotina refrescaExibicao que irá exibir a árvore de arquivos no controle expandida chamando a rotina preencheControle.

 

 Public Sub refrescaExibicao()
        'limpa a arvore existente
        Me.Nodes.Clear()

        'define o primeiro No
        Dim noRaiz_ As New TreeNode(Drive_ & ":\")
        Me.Nodes.Add(noRaiz_)

        preencheControle(noRaiz_)
        Me.Nodes(0).Expand()
    End Sub
6- A rotina preenhceControle exibe os arquivos no controle usando os métodos e propriedades da classe DirectoryInfo do namespace System.IO
 
    Private Sub preencheControle(ByVal DirNo As TreeNode)
 
        Dim dir As New DirectoryInfo(DirNo.FullPath)
        Dim dirItem As DirectoryInfo
        For Each dirItem In dir.GetDirectories
            Dim novoNo As New TreeNode(dirItem.Name)
            DirNo.Nodes.Add(novoNo)
            novoNo.Nodes.Add("*")
        Next
 
    End Sub
7- Abaixo os eventos onBeforeExpand e OnAfterSelect sobrepõe(Overrides) os eventos herdados do controle TreeView.
 
- O evento  onBeforeExpand sobropõe o evento do controle TreeView e inclui a funcionalidade de preencher o controle com os 
arquivos do diretório
 
- O evento OnAfterSelect implementa o evento  DiretorioSelecionado
 
Note que em ambas as rotinas eu estou me referindo aos membros da classe base através da palavra-chave MyBse.


 

    Protected Overrides Sub onBeforeExpand(ByVal e As TreeViewCancelEventArgs)

        MyBase.OnBeforeExpand(e)

        If e.Node.Nodes(0).Text = "*" Then
            e.Node.Nodes.Clear()
            preencheControle(e.Node)
        End If

    End Sub
    Protected Overrides Sub OnAfterSelect(ByVal e As TreeViewEventArgs)
        MyBase.OnAfterSelect(e)
        RaiseEvent DiretorioSelecionado(Me, New DiretorioSelecionadoEventArgs(e.Node.FullPath))
    End Sub
Usando o novo Controle
 
Vamos agora fazer a prova dos 9 e usar o nosso novo controle. Para isto coloque o código abaixo no evento Load 
do formulário form1.vb do projeto:
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'instancia um objeto do tipo DirectoryTree (a nossa classe)
        Dim exibeArquivos As New DirectoryTree()

        'define o tamanho e posição do controle
        exibeArquivos.Size = New Size(Me.Width - 40, Me.Height - 50)
        exibeArquivos.Location = New Point(8, 8)

        'preenche o controle com os aruqivos do drive C 
        exibeArquivos.Drive = "C:\"

        'inclui o controle no formulário
        Me.Controls.Add(exibeArquivos)
    End Sub

 

Elementar !!! basta criar uma instância da classe DirectoryTree e usar seus métodos e propriedades. O resultado é dado abaixo:

 

 

Funciona mesmo...

 

Agora você tem uma classe que implementa uma funcionalidade não existente no VB.NET.

 

Bem , eu apenas dei as preliminares você pode ir além incluindo novas funcionalidades e recursos ao controle. Afinal não vai querer que eu faça tudo sozinho ...

 

Até o próximo artigo VB.NET...

 
Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti