Titulos de um DbGrid transformados em ComboBox

Delphi

21/01/2004

Estimados, gostaria de por a seguinte questão: existe alguma maneira de modificar os títulos das colunas de um DbGrid?

O que pretendo é que os títulos sejam semelhantes a um combobox. Por exemplo numa coluna da DbGrid (nomes de pessoas) essa combo registaria todas as ocorrências diferentes na coluna. Noutra coluna (moradas, por exemplo) registaria todas as ocorrência de moradas e por aí fora. Consegue-se fazer isto?

Obrigado a todos
bacalhau


Bacalhau

Bacalhau

Curtidas 0

Respostas

Motta

Motta

21/01/2004

O nº de ocorrencia de cada coluna pode ser e será diferente, como fazer isto para cada coluna ?

Acho que não entendi o que vc quer


GOSTEI 0
Paulo_amorim

Paulo_amorim

21/01/2004

Olá

bom, mudar o titulo da coluna eh possivel com o comando
     dbgrid.Columns.Items[0].Title.Caption := ´aaa´


mas também nao entendi bem a pergunta...

Até+


GOSTEI 0
Bacalhau

Bacalhau

21/01/2004

Ok, eu ponho a questão de outra maneira. Vamos supor que eu tenho um dbgrid com uma só coluna. Nessa coluna aparecem os seguintes valores:

1
2
2
3
4
4
1

O que eu gostaria de fazer era o titulo da coluna comportar-se como uma combobox, isto é quando fosse clicado mostrar diversas linhas.

Essas linhas seriam as ocorrências dos valores na coluna, isto é, 1, 2, 3 e 4.


GOSTEI 0
Motta

Motta

21/01/2004

na query faça

select distinct coluna
from tabela
where ....


GOSTEI 0
Bacalhau

Bacalhau

21/01/2004

Ceto colega Motta. Mas como fazer o título comportar-se como uma combobox? A verdadeira dificuldade está aí. Nem sei se será possivel sem componentes adicionais


GOSTEI 0
Motta

Motta

21/01/2004

Realmente não sei


GOSTEI 0
Pbjr

Pbjr

21/01/2004

Baixa este [url]http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=338[/url] exemplo que ele deve te mostrar...


GOSTEI 0
Paulo_amorim

Paulo_amorim

21/01/2004

Olá

Embora não seja ´correto´, pode-se tentar uma gambiarra, colocano um combobox invisivel no titulo da coluna...

no OnTitleClick, tornaria o combobox visivel com os valores do grid...

entretanto, isso eh MUITA gambiarra, vê-se logo... :oops:


GOSTEI 0
Bacalhau

Bacalhau

21/01/2004

Colega Paulo_Amorim, de facto já tentei isso há algum tempo, tentando ´ancorar´ um combobox ao título. Mas o resultado foi um desastre. (Pronto já confessei... :oops: )

Mas seria uma forma de solucionar, se essa ´ancoragem´ fosse perfeita. Isto é, ao redimensionar ou mover uma coluna, a combobox ´iria atrás´. Tens alguma ideia de como isto se faz?


GOSTEI 0
Paulo_amorim

Paulo_amorim

21/01/2004

Olá

Ainda tenho vergonha disso...ahaha

Que tal se vc travasse a largura da coluna? o usuario nao poderia mudar e nao descobriria...nao serve?


GOSTEI 0
Bacalhau

Bacalhau

21/01/2004

Paulo, na realidade a ideia não é tão louca assim. Não haverá forma de a combobox se deslocar e dimensionar da mesma forma da coluna?

Deve haver alguma propriedade meio louca, mas sinceramente não sei.


GOSTEI 0
Paulo_amorim

Paulo_amorim

21/01/2004

Olá

Realmente deve ter!...

E se em algum evento de resize da coluna vc fizesse o Combo.Width receber o tamanho da coluna...?nao eh possivel???

Vou tentar aqui tambem...

Se conseguir, e puder me informar, ficaria grato!

Até+


GOSTEI 0
Bacalhau

Bacalhau

21/01/2004

Exactamente. Não só redimensionar como mover-se sempre que a coluna é movida. Se conseguires alguma coisa diz

abraço
bacalhau


GOSTEI 0
Beppe

Beppe

21/01/2004

Tem umas coisas que não entendi:

1) O título da coluna se pareceria sempre com uma combo, com setinha e caixa de texto e tudo?
2) a combo abre por sobre as células?
3) Quando um item é escolhido faz o que?


GOSTEI 0
Bacalhau

Bacalhau

21/01/2004

Beppe, cá vão as respostas

1. Sim. A ideia é que o título se comporte como uma combobox. É exactamente isso

2. Certo. É aberto o seu conteúdo por cima dos valores da coluna.

3. Quando for clicado um item ele deverá ir para o registo cujo valor é o clicado.

Este comportamento pode ser visto no Excel, quando organizamos a informação e pretendemos ordenar, filtrar, pesquisar, etc.


GOSTEI 0
Beppe

Beppe

21/01/2004

Catita, eu fiz um negócinho simples, só que dá cintilização...

No OnDrawCell:
if ARow = 0 then
begin
  if (ACol = 1) then
  begin
    OffsetRect(Rect, StringGrid1.Left, StringGrid1.Top);
    if not EqualRect(ComboBox1.BoundsRect, Rect) then
      ComboBox1.BoundsRect := Rect;
  end;
end;


Eu generalizei, mas é fácil adaptar o [b:027fb8357e]if [/b:027fb8357e]pra um [b:027fb8357e]for[/b:027fb8357e].
Deve haver uma maneira de contonar o problema do pisca-pisca, mas os métodos óbvios são estáticos, em vez de virtuais. Vou dar mais uma investigada, se achar algo eu posto.


GOSTEI 0
Beppe

Beppe

21/01/2004

bcalhau, cheguei nisso aqui:

type
  TComboGrid = class(TStringGrid)
  private
    Combos: TList;
  protected
    procedure SizeChanged(OldColCount, OldRowCount: Longint); override;
    procedure ComboBoxDropDown(Sender: TObject); virtual;
    procedure CalcSizingState(X, Y: Integer; var State: TGridState;
      var Index: Longint; var SizingPos, SizingOfs: Integer;
      var FixedInfo: TGridDrawInfo); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure UpdateCombos;
  end;

...

{ TComboGrid }

constructor TComboGrid.Create(AOwner: TComponent);
begin
  inherited;

  Combos := TList.Create;
end;

destructor TComboGrid.Destroy;
begin
  Combos.Free;

  inherited;
end;

procedure TComboGrid.CalcSizingState(X, Y: Integer; var State: TGridState;
  var Index, SizingPos, SizingOfs: Integer; var FixedInfo: TGridDrawInfo);
begin
  inherited;

  // creio que aqui se concentraria a lógica para
  // atalizar as combobox após redimensionar uma coluna
  if State = gsColSizing then
    UpdateCombos;
end;

procedure TComboGrid.SizeChanged(OldColCount, OldRowCount: Integer);
begin
  inherited;

  // o tamanho foi mudado, atualiza
  UpdateCombos;
end;

procedure TComboGrid.UpdateCombos;
var
  I, L: Integer;
begin
  for I := Combos.Count to ColCount - 2 do
  begin
    Combos.Add(TComboBox.Create(Self));
    TComboBox(Combos[I]).Parent := Self;
    TComboBox(Combos[I]).Tag := I + 1;
    TComboBox(Combos[I]).OnDropDown := ComboBoxDropDown;
  end;

  L := ColWidths[0];
  I := 1;
  while I < ColCount do
  begin
    TComboBox(Combos[I - 1]).BoundsRect := Bounds(L + I + 2, 1, ColWidths[I] - 2, RowHeights[I] - 2);
    Inc(L, ColWidths[I]);
    Inc(I);
  end;
end;

procedure TComboGrid.ComboBoxDropDown(Sender: TObject);
var
  I: Integer;
begin
  with Sender as TComboBox do
  begin
    // a combo está para ser aberta
    // adiciona os items à sua lista
    Items.Clear;
    for I := 1 to RowCount - 1 do
      Items.Add(Cells[Tag, I]);
  end;
end;


É praticamente impossível fazer o que você quer sem herdar. Note que ainda não é perfeito, a procedure UpdateCombos provavelmente precisará ser chamada pelos clientes sempre que for alterada alguma dimensão.

Exemplo de uso:
with TComboGrid.Create(Self) do
begin
  BoundsRect := StringGrid1.BoundsRect;
  ColCount := 8;
  Width := Width * 2 - 250;
  UpdateCombos;
  Parent := Self;
end;



GOSTEI 0
Spider

Spider

21/01/2004

Existe um programa, EMS PostgreSQL Manager, que faz isto que vc quer, só que ele não usa combobox...

ele usa botões e listbox(acho)

ele coloca pequenos botoes com o glyph de uma seta para baixo nas colunas que deseja, e, ao clicar neste botão exibe um listbox com todas as ocorrecias(sem repetir) da coluna em questão!

naum tenho idéia agora de como implementar, mas acho que vale a dica...


GOSTEI 0
POSTAR