Método de Extensão para encontrar controles em Windows Forms

Recentemente em uma thread nos fóruns do MSDN respondi uma pergunta que me levou a compartilhar aqui a solução. A dúvida era criar um método para localizar os controles do tipo PictureBox existentes em um formulário.

A solução, que é relativamente simples, seria criar um método recursivo para fazer um loop na coleção de controles do formulário e ir testando esses controles para verificar se cada controle é do tipo PictureBox. Como existem controles que são containers (contém outros controles), o método seria chamado novamente, dai a recursividade.

Vamos estender a funcionalidade acima para qualquer tipo de controle fazendo com o que o nosso tipo seja o parâmetro para o método, logo podemos criar um método genérico no formulário. Veja o método logo abaixo.

public partial class SeuForm : Form
{
    public SeuForm()
    {
        InitializeComponent();
    }

    private List<T> GetChildControls<T>(Control c, bool recursive)
        where T : Control
    {
        // lista de controles
        var childControlsList = new List<T>();

        // adiciona controles na lista de controles
        childControlsList.AddRange(c.Controls.OfType<T>());

        // verifica se o método é recursivo e realiza
        // um loop nos filhos
        if (recursive)
        {
            foreach (Control ctrl in c.Controls)
                childControlsList.AddRange(this.GetChildControls<T>(ctrl, true));
        }

        return childControlsList;
    }
}

Vejam que anteriormente escrevi: “…fazer um loop na coleção de controles do formulário e ir testando esses controles para verificar se cada controle é do tipo PictureBox.”. Para isso, o método acima utiliza o método de extensão OfType.

O parâmetro recursive tem por objetivo informar o método que queremos torná-lo recursivo, ou seja, se verdadeiro queremos que o método liste os controles mesmo que estes estejam contidos em outros controles containers.

Ok, isso resolve o problema. Mas podemos melhorar essa solução?

Sim, podemos reutilizar o método em outros projetos criando um método de extensão para a classe Control, que é a classe base para todos os controles Windows Forms.

Temos então a classe abaixo que pode ser criada em uma Class Library e então ser reutilizada em outros projetos.

public static class ControlExtensions
{
    public static List<T> GetChildControls<T>(this Control c, bool recursive)
        where T : Control
    {
        // lista de controles
        var childControlsList = new List<T>();

        // adiciona controles na lista de controles
        childControlsList.AddRange(c.Controls.OfType<T>());

        // verifica se o método é recursivo e realiza
        // um loop nos filhos
        if (recursive)
        {
            foreach (Control ctrl in c.Controls)
                childControlsList.AddRange(ctrl.GetChildControls<T>(true));
        }

        return childControlsList;
    }
}

É algo simples, mas que achei que seria interessante compartilhar essa solução.

Para finalizar, vale a pena conferir essa solução do Israel Aece e essa biblioteca do Márcio Althmann. Não são relacionadas com Windows Forms mas utilizam métodos de extensão para outras finalidades.

Links de ajuda:

Control class
http://bit.ly/PbbG9

Control.ControlCollection class
http://bit.ly/dAV7rI

Enumerable.OfType<TResult> Method
http://bit.ly/boCA6y

Nenhum comentário:

Postar um comentário