2015-10-02 1 views
3

Je voudrais ajouter DBLookupCombobox à certaines colonnes d'un DBGrid. Il y a un bel article sur About.com sur la façon de le faire here. Le problème est qu'avec une table comportant plusieurs colonnes, si vous sélectionnez DBLookupCombobox dans une colonne et que vous essayez ensuite de faire défiler vers la gauche, la liste déroulante se déplace également vers la gauche, comme indiqué dans les images incluses. Comment le code About.com peut-il être modifié pour empêcher ce comportement? Une recherche sur le Web a montré deux autres se plaignant du même problème avec aucune solution. Notez que je veux utiliser un DBLookupCombobox pour afficher un nom mais entrer l'identifiant, donc l'utilisation d'une liste simple ne suffira pas.Ajouter DBLookupCombobox à Delphi DBGrid

using combobox scroll left

procedure TForm1.DBGrid1ColExit(Sender: TObject); 
begin 
    if DBGrid1.SelectedField.FieldName = DBLookupComboBox1.DataField then 
    DBLookupComboBox1.Visible := False 
end; 

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; 
    DataCol: Integer; Column: TColumn; State: TGridDrawState); 
begin 
    if (gdFocused in State) then 
    begin 
    if (Column.Field.FieldName = DBLookupComboBox1.DataField) then 
    with DBLookupComboBox1 do 
    begin 
     Left := Rect.Left + DBGrid1.Left + 2; 
     Top := Rect.Top + DBGrid1.Top + 2; 
     Width := Rect.Right - Rect.Left; 
     Width := Rect.Right - Rect.Left; 
     Height := Rect.Bottom - Rect.Top; 

     Visible := True; 
    end; 
    end 
end; 

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char); 
begin 
    if (key = Chr(9)) then Exit; 

    if (DBGrid1.SelectedField.FieldName = DBLookupComboBox1.DataField) then 
    begin 
    DBLookupComboBox1.SetFocus; 
    SendMessage(DBLookupComboBox1.Handle, WM_Char, word(Key), 0); 
    end 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
with DBLookupComboBox1 do 
begin 
    DataSource := DataSource1; // -> AdoTable1 -> DBGrid1 
    ListSource := DataSource2; 
    DataField := 'resource_id'; // from AdoTable1 - displayed in the DBGrid 
    KeyField := 'id'; 
    ListField := 'resource_name; id'; 

    Visible := False; 
end; 

DataSource2.DataSet := AdoQuery1; 

AdoQuery1.Connection := AdoConnection1; 
AdoQuery1.SQL.Text := 'SELECT id,resource_name FROM resources'; 
AdoQuery1.Open; 
end; 
+0

Le lien vers le code About.com n'est pas suffisant. Nous avons besoin de * votre * code (un MCVE) pour démontrer le problème. Il fonctionne apparemment avec le code sur About, comme d'autres l'ont utilisé (y compris moi) sans problème. –

+0

Peut-être que c'est un problème Delphi alors. J'ai collé le code verbatim dans un nouveau projet (à l'exception de mes références de données) et voir ce comportement à la fois sur Delphi XE et Delphi 2006. – fullerm

+0

Encore une fois, un MCVE aiderait. J'ai utilisé le code dans Delphi 2007 sans problème. Je ne peux pas voir ce que tu as fait d'ici. Si vous voulez de l'aide pour votre code, incluez le code dans votre question. Un lien vers le code de quelqu'un d'autre n'est pas bénéfique, et nous ne devrions pas avoir à quitter ce site pour comprendre ce que vous demandez. –

Répondre

1

Voici une solution en utilisant un hack propre de François.

type 
    // Hack to redeclare your TDBGrid here without the the form designer going mad 
    TDBGrid = class(DBGrids.TDBGrid) 
     procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL; 
    end; 

    TForm1 = class(TForm) 
[...] 
procedure TDBGrid.WMHScroll(var Msg: TWMHScroll); 
begin 
    if Form1.DBGrid1.SelectedField.FieldName = Form1.DBLookupComboBox1.DataField then begin 
    case Msg.ScrollCode of 
     SB_LEFT,SB_LINELEFT,SB_PAGELEFT: begin 
     Form1.DBGrid1.SelectedIndex := Form1.DBGrid1.SelectedIndex-1; 
     Form1.DBLookupComboBox1.Visible := False; 
     end; 
     SB_RIGHT,SB_LINERIGHT,SB_PAGERIGHT: begin 
     Form1.DBGrid1.SelectedIndex := Form1.DBGrid1.SelectedIndex+1; 
     Form1.DBLookupComboBox1.Visible := False; 
     end; 
    end; 
    end; 
    inherited; // to keep the expected behavior 
end;