Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

bruno_pascal

DbGrid e sua ScrollBar

Recommended Posts

Boa noite a todos deste fórum

 

Estou dando meus primeiros passos em programação delphi e estou com uma dúvida que me incomoda e que por sinal ainda não consegui achar na net uma solução concreta para o problema.

 

Só para exemplificar de forma simples : criei um banco de dados mysql onde desejo visualizar todos os nomes de pessoa em um dbgrid do delphi 7 contido no formulário. Porém, quando estou em modo de execução do programa , ao clicar na barra de rolagem vertical do dbgrid , ele "pula" do primeiro para o último registro e isso acaba se tornando um efeito indesejável , pois gostaria que ao clicar na barra de rolagem fossem exibidos os nomes selecionados um a um , como nos botões que criei de anterior e próximo.

 

Alguém poderia me dizer em forma de código o procedimento para solucionar este problema? Estou começando a aprender o delphi e fico muito agradecido se alguém souber e puder ajudar .

 

Desde já obrigado a todos .

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sinceramente, não sei porque acontece esse problema com o DBgrid. Não sei se é algum bug, se falta algum código ou se é preciso fazer algum procedimento em design time, para que os dados sejam exibidos um a um assim que for clicada a barra de rolagem vertical do DBGrid.

 

Estou aprendendo programação em delphi e por isso não tenho nenhuma noção de como usar o listview. Parece que para carregar os dados no DBGrid é diferente, tem que lidar com colunas e linhas e além disso até os botões anterior e próximo muda a codificação. Eu gostaria de poder criar uma tabela semelhante ao DBGrid com barras de rolagem vertical e horizontal carregando os dados do meu banco de dados mysql, e que quando eu clicasse na barra de rolagem vertical que fosse exibida a linha selecionada uma a uma. Será que isso é viável no listview?

 

Só para efeito de teste e para ilustrar a situação, criei um banco de dados Mysql chamado dados. Em seguida , criei uma tabela contatos. Nessa tabela, criei a coluna Nome . No DBGrid, os nomes são carregados . Além disso adicionei botões anterior e próximo.

Teria alguma sugestão em forma de código ou você sabe dizer o procedimento a ser feito para que isso seja reproduzido de forma semelhante ao DBGrid ,porém , do jeito que te disse em relação a barra de rolagem vertical?? Se tiver alguma sugestão ficarei muito agradecido. Pode até utilizar esse exemplo sobre a coluna nome que te disse mesmo.

 

obrigado pela atenção

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom você pode desativar as barras de rolagem e colocar um botão para baixo

 

com o código

 

if (ListView1.Selected.Index < (ListView1.Items.Count - 1)) then
    ListView1.Items[ListView1.Selected.Index + 1].Selected := true;

 

e no botão para cima

 

if ((ListView1.Selected.Index + 1) > -1) then
    ListView1.Items[ListView1.Selected.Index - 1].Selected := true;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Hum entendi. Vou realizar esse procedimento. Sem querer explorar sua boa vontade, mas me surgiram 2 dúvidas . Primeira : Como eu faria para carregar todos os nomes no listview assim que o formulário fosse exibido? Segunda : Gostaria também que ao clicar numa determinada linha do listview que fosse exibido o nome contido no listview no interior do Tedit nome presente no formulário;

 

Com relação aos botões para baixo e para cima do listview , gostaria que atualizasse o Tedit nome também.

 

Detalhes adicionais :

 

Estou usando os seguintes componentes :

 

Zconnection

ZQuery

DataSetProvider

ClientDataSet

DataSource

 

Obg aí por tentar me ajudar Roberto.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom primeiramente você só precisará do ZConnection e do ZQuery

 

No evento OnShow do Formulário você vai colocar para preencher os registros no ListView

 

procedure  var    Query : TZQuery;    SQL : String;    Item : TListViewItem;  begin    SQL := 'Seu comando QSL';    Query := Sua_Query;    Query.Close;    Query.SQL.Clear;    Query.SQL.Add(SQL);    Query.Open;    while not (Query.Eof) do      begin        Item := ListView1.Items.Add;        Item.Caption := Query.FieldByName('Seu_Campo_do_select').AsString;        Item.SubItems.Add(Query.FieldByName('Seu_Campo_do_select').AsString);        //Se precisar adicionar mais subitems só repitir a linha de cima        Query.Next;      end;    Query.Close;  end;
 
  • Altere a propriedade ViewStyle para vsReport;
  • Altere a propriedade MultiSelect para false;
  • E em tempo de projeto adicione suas colunas na propriedade columns;
Ops desculpe cara a propriedade ViewStyle tem que ser vsDetails;

 

 

No evento on dblClick coloque o seguinte:

 

procedure  begin    if (ListView1.SelCount > 0) then      edit1.Text := ListView1.Selected.Caption;  end;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi Roberto, tentei fazer o que vc me disse mas por algum motivo algo não deu certo . Veja o código como está :

 

procedure TForm1.FormShow(Sender: TObject);
var
Query : TZQuery;
SQL : String;
Item : TListViewItem;
begin
SQL:= 'Select * from contatos';
Query := ZQuery1;
Query.Close;
Query.SQL.Clear ;
Query.SQL.Add(SQL);
Query.Open;

while not (Query.Eof) do
      begin
        Item := ListView1.Items.Add;
        Item.Caption := Query.FieldByName('nome').AsString;
        Item.SubItems.Add(Query.FieldByName('nome').AsString);
        //Se precisar adicionar mais subitems só repitir a linha de cima
        Query.Next;
      end;
      Query.Close;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
begin
 if (ListView1.SelCount > 0) then
      Edit_Nome.Text := ListView1.Selected.Caption;
end;

end.

Na linha que vc diz Query:= 'Sua Query' , no caso você está querendo dizer que em seu lugar deve-se por o nome da query?

 

Estou usando Delphi 7 e não existe vsDetails na propriedade ViewStyle do listview não. Só existe vsIcon, vsList, vsReport e vsSmallIcon. Pelo menos aqui no meu é assim. Então havia usado o vsReport e alterado a coluna para nome.

 

Na parte que carrega o listview que diz 'seu_campo_do_select' eu coloquei o nome do campo (que é nome) tanto em Items.Caption quanto em Items.SubItems.Add.

 

O erro que aparece é "Undeclared Identifier TListViewItem" . Nem chega a carregar o formulário. Outra coisa também é que na propriedade Active do ZQuery está como False e na propriedade SQL eu deixei em branco.

 

Tenho no formulário ZConnection, ZQuery, Edit e ListView.

Poderia dar um olhada por favor no código que acabei de mandar pra ver se tem algo de errado?

 

obg.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tudo bem, não tem problema não. É que as vezes a gente acaba se confundindo mesmo. Ajeitei aqui e já está carregando legal no listview. Quando eu clico 2x na linha do listview aparece do Edit_Nome. Já está ficando bem melhor. Mas tenho umas observações a fazer : Por exemplo : Assim que o formulário é carregado , não aparece no Edit_Nome o primeiro nome da lista. Está em branco. Daí quando clico no botão que vc mandou o código para percorrer o listview, então dá erro. Gostaria também que ao percorrer o listview que fosse atualizado o nome no edit_Nome.

 

No meu Delphi 7 também não tem a propriedade vsDetail. Então o listview fica sem aquelas "linhas" separando um registro do outro , daí não sei se teria algum jeito de por ele igual ao DBGrid em termos de aparência.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Coloquei o código para selecionar a primeira linha conforme sua orientação. Agora já aparece o primeiro nome no edit_Nome. Então aproveitei a sua idéia e implementei uma linha de código para atualizar o edit_Nome , assim que os botões anterior e próximo são acionados.

 

Mudei também a propriedade do listview chamada HideSelection para False. Agora já aparece a linha selecionada, só que não aparece aquela linha azul destacada. Aparece na cor bege bem clara. Se tivesse como mudar essa cor selecionada, seria melhor. Sabe dizer se tem por meio de código ou de alguma propriedade para alterar a cor da linha selecionada?

 

Outra coisa também é que quando estou no primeiro registro e aperto o botão anterior, então dá um erro "Exception class EAcessViolation".

 

Meu código está assim :

 

procedure TForm1.FormShow(Sender: TObject);
var
Query : TZQuery;
SQL : String;
Item : TListItem;
begin
SQL:= 'Select * from contatos';
Query := ZQuery1;
Query.Close;
Query.SQL.Clear ;
Query.SQL.Add(SQL);
Query.Open;

while not (Query.Eof) do
      begin
        Item := ListView1.Items.Add;
        Item.Caption := Query.FieldByName('nome').AsString;
        Item.SubItems.Add(Query.FieldByName('nome').AsString;
        //Se precisar adicionar mais subitems só repitir a linha de cima
        Query.Next;

      end;
      Query.Close;
       ListView1.Items[0].Selected := true;      //---------- Código após o laço
       Edit_Nome.Text := ListView1.Items[0].Caption;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
begin
 if (ListView1.SelCount > 0) then
  edit_Nome.Text := ListView1.Selected.Caption;
end;

procedure TForm1.btnAnteriorClick(Sender: TObject);
begin
if ((ListView1.Selected.Index + 1) > -1) then
    ListView1.Items[ListView1.Selected.Index - 1].Selected := true;
    edit_Nome.Text := ListView1.Selected.Caption;  //linha acrescentada também
end;

procedure TForm1.btnProximoClick(Sender: TObject);
begin
if (ListView1.Selected.Index < (ListView1.Items.Count - 1)) then
    ListView1.Items[ListView1.Selected.Index + 1].Selected := true;
    edit_Nome.Text := ListView1.Selected.Caption; //linha acrescentada também
end;

end.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estive analisando aqui também o seguinte : Coloquei um monte de nomes no banco de dados .Estando com a barra de rolagem vertical, quando eu clico no botão próximo não aparecem os nomes que estão bem mais abaixo no listview, pois ela não acompanha os registros ficando imóvel e muito menos estando sem a barra de rolagem. É como se a linha selecionada no listview "descesse por trás do formulário". Só quando clico na barra de rolagem ao invés de clicar no botão próximo é que dá pra ver os nomes que estão mais abaixo . Vê só se confere o que digo.

 

De qualquer forma agradeço pela paciência e dedicação em responder minhas dúvidas .

Compartilhar este post


Link para o post
Compartilhar em outros sites

No botão pra cima troque:

 

> -1

 

por:

 

> 0

 

Para aparecer as linhas marque a propriedade GridLines para true.

 

para aparecer os itens de baixo ative a barra de rolagem.



Para ficar mais bonito marque a propriedade FullRowSelect como true

Compartilhar este post


Link para o post
Compartilhar em outros sites

Troquei no botão para cima por 0 e o mesmo erro continua....será que é preciso fazer um try--except?Não sei também se isso daria certo. Se fosse como ficaria?

 

É aí que está o problema. Assim que executo o programa, a barra de rolagem aparece, mas quando clico no botão para baixo, a barra de rolagem não acompanha os registros. Ela fica parada e as linhas selecionadas passam por baixo do formulário. Dai se eu quiser ver os contatos mais abaixo eu tenho que mover a barra de rolagem , mas não pelo botão para baixo. É assim mesmo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

O código do botão pra cima fica isso:

 

if ((ListView1.Selected.Index) > 0) then
    ListView1.Items[ListView1.Selected.Index - 1].Selected := true;
  Edit1.Text := ListView1.Selected.Caption;
  if (ListView1.Selected.Index > 0) then
    ListView1.Scroll(ListView1.Items[ListView1.Selected.Index - 1].Position.X, ListView1.Items[ListView1.Selected.Index - 1].Position.Y)
  else
    ListView1.Scroll(4, 4);
  ListView1.SetFocus;

esse do botão pra cima ta com um bug no primeiro item, depois eu olho.

 

E esta ai o do botão para baixo:

 

if (ListView1.Selected.Index < (ListView1.Items.Count - 1)) then
    ListView1.Items[ListView1.Selected.Index + 1].Selected := true;
  Edit1.Text := ListView1.Selected.Caption;
  ListView1.Scroll(ListView1.Items[ListView1.Selected.Index - 1].Position.X, ListView1.Items[ListView1.Selected.Index - 1].Position.Y);
  ListView1.SetFocus;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Consegui resolver o BUG

 

Botão para cima:

if ((ListView1.Selected.Index) > 0) then
    ListView1.Items[ListView1.Selected.Index - 1].Selected := true;
  Edit1.Text := ListView1.Selected.Caption;
  ListView1.Items[ListView1.Selected.Index].MakeVisible(true);
  ListView1.SetFocus;

 

Botão para baixo:

if (ListView1.Selected.Index < (ListView1.Items.Count - 1)) then
    ListView1.Items[ListView1.Selected.Index + 1].Selected := true;
  Edit1.Text := ListView1.Selected.Caption;
  ListView1.Items[ListView1.Selected.Index].MakeVisible(true);
  ListView1.SetFocus;


Outra observação que eu deixo para esse seu código é o seguinte:

 

Evite usar asterisco no seu select pois demora maia para realizar a consulta, sempre informe apenas os campos que você vai precisar separados por virgula no lugar do asterisco.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi Roberto, de fato você conseguiu resolver o meu problema e chegou aonde realmente eu queria. Agora está tudo funcionando perfeitamente ! Quero agradecer mais uma vez pelo empenho,dedicação , perseverança e por ter me dado essa sugestão sobre o listview me mostrando toda a codificação do programa com enorme paciência . Parabéns e muito obrigado !. Se você tiver alguma sugestão de livro ou apostila que sejam bons para estudar Delphi e também banco de dados , você me fala. Já pode marcar o tópico como resolvido.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom eu não sei dizer nenhum tipo de livro, até porque eu aprendi na marra.

Quando preciso fazer alguma coisa saio pesquisando e fuçando pra tentar fazer, a unica coisa que fiz foi um curso técnico na ETEC

e agora estou correndo atrás de uma faculdade.

 

Quando precisar de ajuda só pedir, estarei disposto a ajudar.

vlw

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.