none
Como ter acesso a um elemento do Form1 a partir de outra classe? RRS feed

  • Pergunta

  • Olá, desejo algo em tese bem simples:  Tenho uma classe que conecta um banco de dados (DataBaseManagement) e um fomulário (Form1) com um Datagridview (listadados). O problema é que o DatagridView listadados não é reconhecido (nome não existe no contexto atual.

    Tentei instanciar um novo objeto do tipo form1 dentro da classe DatabBase Management mas mesmo assim o DataGridView listadados não é reconhecido. Sei que deve ser algo simples, mas não consigo resolver. Abaixo segue meu código:

    class DataBaseManagement
        {
    
    
    
            // - FUNÇÃO DE CONEXÃO AO BANCO DE DADOS
            //========================================================================================
            public void ConectarDB()
            {
    
                const string filename = @"F:\Programação\Banco de Dados\teste.s3db";
                const string query = "select * from table1;";
                var cone = new SQLiteConnection("Data Source=" + filename + ";Version=3;");
    
                try
                {
    
                    DataSet ds = new DataSet();
                    cone.Open();
                    var da = new SQLiteDataAdapter(query, cone);
                    da.Fill(ds);
    
    
                    Form1 f = new Form1();
    
                    f.listadados.DataSource = ds.Tables[0].DefaultView;
    
                  
    
                    SQLiteCommand createCommand = new SQLiteCommand(query, cone);
                    SQLiteDataReader dr = createCommand.ExecuteReader();
    
    
                    cone.Close();
                }
    
                catch (Exception)
                {
                    throw;
                }
    
    
            }
    
            //========================================================================================
    
    
    
        }

    Agradeço qualquer ajuda. Obrigado.

    segunda-feira, 29 de janeiro de 2018 13:34

Respostas

  • Não é questão de segurança, é questão de acoplamento e acúmulo de responsabilidade.

    Exemplo: Imagine se você por alguma razão resolve trocar o seu componente de Grid, não faz sentido ter que recompilar seu projeto de acesso a dados devido a uma mudança de componentes de UI (interface de usuário).

    Exemplo 2: Você não deveria precisar recompilar o projeto de UI devido a uma mudança de SGBD (de SQL Server para Oracle, por exemplo).

    Por isso, o recomendado é solicitar à devida classe que busque os dados, retorne-os e sua UI consome (exibe) estes dados, sem se importar de onde vieram.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.


    terça-feira, 30 de janeiro de 2018 11:19

Todas as Respostas

  • Olá Denis Valjean

    Modifica a propriedade de seu grid  Modifiers de Private para Public

     Abraços!

    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Microsoft Developer .NET
    Microsoft Certified Professional
    Development Leader at JAMSOFT Informática
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    segunda-feira, 29 de janeiro de 2018 14:45
  • Olá Denis Valjean

    Modifica a propriedade de seu grid  Modifiers de Private para Public

     Abraços!

    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Microsoft Developer .NET
    Microsoft Certified Professional
    Development Leader at JAMSOFT Informática
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    Olá Rafael, infelizmente já tinha feito isso e não mostra nada no datagridview. Quando coloco o código dentro do Form1 vai tudo beleza. O código compila e roda, mas o datagrid fica vazio. :(
    segunda-feira, 29 de janeiro de 2018 19:10
  • Realmente não irá funcionar, a noite eu irei lhe ajudar nisso!

    Falta alguns detalhes, ai, por exemplo Form1 é seu form principal?

    Você está criando uma nova instancia do Form1 e não abre ele!

    Iremos organizar esse código... blz!


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Microsoft Developer .NET
    Microsoft Certified Professional
    Development Leader at JAMSOFT Informática
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    segunda-feira, 29 de janeiro de 2018 19:32
  • Realmente não irá funcionar, a noite eu irei lhe ajudar nisso!

    Falta alguns detalhes, ai, por exemplo Form1 é seu form principal?

    Você está criando uma nova instancia do Form1 e não abre ele!

    Iremos organizar esse código... blz!


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Microsoft Developer .NET
    Microsoft Certified Professional
    Development Leader at JAMSOFT Informática
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    Sim, estou apenas começando com um Form1 único. Apenas um form. Tentei usar o código do Lucio mas dá problema no Databind.
    segunda-feira, 29 de janeiro de 2018 19:59
  • Certo deixa te adiantar algo logo então!

    Depois podemos melhorar tá, mude sua classe para isso:

    class DataBaseManagement
    {
        const string filename = @"F:\Programação\Banco de Dados\teste.s3db";
        const string query = "select * from table1;";
        SQLiteConnection cone = new SQLiteConnection("Data Source=" + filename + ";Version=3;");
    
        // - FUNÇÃO DE CONEXÃO AO BANCO DE DADOS
        //========================================================================================
        public DataTable GetDados()
        {
            try
            {
                cone.Open();
                var dados = new DataTable();
                var da = new SQLiteDataAdapter(query, cone);
                da.Fill(dados);
                cone.Close();
                return dados;
            }
    
            catch (Exception)
            {
                throw;
            }
        }
        //========================================================================================
    }

    No evento Load de seu form coloca isso:

     listadados.DataSource = new DataBaseManagement().GetDados();

    Com isso já irá funcionar o que precisa.

    Abraços!


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Microsoft Developer .NET
    Microsoft Certified Professional
    Development Leader at JAMSOFT Informática
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    segunda-feira, 29 de janeiro de 2018 20:11
  • Certo deixa te adiantar algo logo então!

    Depois podemos melhorar tá, mude sua classe para isso:

    class DataBaseManagement
    {
        const string filename = @"F:\Programação\Banco de Dados\teste.s3db";
        const string query = "select * from table1;";
        SQLiteConnection cone = new SQLiteConnection("Data Source=" + filename + ";Version=3;");
    
        // - FUNÇÃO DE CONEXÃO AO BANCO DE DADOS
        //========================================================================================
        public DataTable GetDados()
        {
            try
            {
                cone.Open();
                var dados = new DataTable();
                var da = new SQLiteDataAdapter(query, cone);
                da.Fill(dados);
                cone.Close();
                return dados;
            }
    
            catch (Exception)
            {
                throw;
            }
        }
        //========================================================================================
    }

    No evento Load de seu form coloca isso:

     listadados.DataSource = new DataBaseManagement().GetDados();

    Com isso já irá funcionar o que precisa.

    Abraços!


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Microsoft Developer .NET
    Microsoft Certified Professional
    Development Leader at JAMSOFT Informática
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    Grato pela ajuda! Parece que você criou um método publico na minha classe e chamou ele no form. Entendi. Mas não haveria um jeito (seguro) de instanciar o conteúdo do datagrid  do Form1 da forma que eu estava tentando? Porque funciona com outras classes mas não com os Forms? O que eles tem de diferente? Por que simplesmente Form1 f = new Form1() não funciona neste caso? GET/SET ajudaria nesse caso?
    segunda-feira, 29 de janeiro de 2018 22:11
  • Denis,

    Passar para sua classe de dados a responsabilidade de preencher o DataGrid é uma prática ruim. Mas apenas para que entenda como que teria que ser pro seu código funcionar, segue exemplo:

    class DataBaseManagement
        {
    
    
    
            // - FUNÇÃO DE CONEXÃO AO BANCO DE DADOS
            //========================================================================================
            public void ConectarDB(Form1 f) // note que você terá que passar uma referência para o form aberto
            {
    
                const string filename = @"F:\Programação\Banco de Dados\teste.s3db";
                const string query = "select * from table1;";
                var cone = new SQLiteConnection("Data Source=" + filename + ";Version=3;");
    
                try
                {
    
                    DataSet ds = new DataSet();
                    cone.Open();
                    var da = new SQLiteDataAdapter(query, cone);
                    da.Fill(ds);
    
                    // Usando o parâmetro f do método e considerando que listadados está como public no Form1
                    f.listadados.DataSource = ds.Tables[0].DefaultView;
    
                  
    
                    SQLiteCommand createCommand = new SQLiteCommand(query, cone);
                    SQLiteDataReader dr = createCommand.ExecuteReader();
    
    
                    cone.Close();
                }
    
                catch (Exception)
                {
                    throw;
                }
    
    
            }
    
            //========================================================================================
    
    
    
        }

    Aí no seu Form1, na chamada para o método ConectarDB você passaria o form atual (Form1) como referência, usando o this, por exemplo.

    Mas novamente, isso é uma prática ruim, mas isso é outra conversa. 

    Abraço.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

    terça-feira, 30 de janeiro de 2018 10:19
  • Denis,

    Passar para sua classe de dados a responsabilidade de preencher o DataGrid é uma prática ruim. Mas apenas para que entenda como que teria que ser pro seu código funcionar, segue exemplo:

    class DataBaseManagement
        {
    
    
    
            // - FUNÇÃO DE CONEXÃO AO BANCO DE DADOS
            //========================================================================================
            public void ConectarDB(Form1 f) // note que você terá que passar uma referência para o form aberto
            {
    
                const string filename = @"F:\Programação\Banco de Dados\teste.s3db";
                const string query = "select * from table1;";
                var cone = new SQLiteConnection("Data Source=" + filename + ";Version=3;");
    
                try
                {
    
                    DataSet ds = new DataSet();
                    cone.Open();
                    var da = new SQLiteDataAdapter(query, cone);
                    da.Fill(ds);
    
                    // Usando o parâmetro f do método e considerando que listadados está como public no Form1
                    f.listadados.DataSource = ds.Tables[0].DefaultView;
    
                  
    
                    SQLiteCommand createCommand = new SQLiteCommand(query, cone);
                    SQLiteDataReader dr = createCommand.ExecuteReader();
    
    
                    cone.Close();
                }
    
                catch (Exception)
                {
                    throw;
                }
    
    
            }
    
            //========================================================================================
    
    
    
        }

    Aí no seu Form1, na chamada para o método ConectarDB você passaria o form atual (Form1) como referência, usando o this, por exemplo.

    Mas novamente, isso é uma prática ruim, mas isso é outra conversa. 

    Abraço.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

         Obrigado, então isso que dizer que seria mais seguro eu preencher o datagrid no evento formload ou  com um método dentro da própria classe Form1, certo?
    terça-feira, 30 de janeiro de 2018 11:01
  • Não é questão de segurança, é questão de acoplamento e acúmulo de responsabilidade.

    Exemplo: Imagine se você por alguma razão resolve trocar o seu componente de Grid, não faz sentido ter que recompilar seu projeto de acesso a dados devido a uma mudança de componentes de UI (interface de usuário).

    Exemplo 2: Você não deveria precisar recompilar o projeto de UI devido a uma mudança de SGBD (de SQL Server para Oracle, por exemplo).

    Por isso, o recomendado é solicitar à devida classe que busque os dados, retorne-os e sua UI consome (exibe) estes dados, sem se importar de onde vieram.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.


    terça-feira, 30 de janeiro de 2018 11:19
  • Não é questão de segurança, é questão de acoplamento e acúmulo de responsabilidade.

    Exemplo: Imagine se você por alguma razão resolve trocar o seu componente de Grid, não faz sentido ter que recompilar seu projeto de acesso a dados devido a uma mudança de componentes de UI (interface de usuário).

    Exemplo 2: Você não deveria precisar recompilar o projeto de UI devido a uma mudança de SGBD (de SQL Server para Oracle, por exemplo).

    Por isso, o recomendado é solicitar à devida classe que busque os dados, retorne-os e sua UI consome (exibe) estes dados, sem se importar de onde vieram.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.


    ok.entendi. Obrigado!!
    terça-feira, 30 de janeiro de 2018 13:10