Rzecz tkwi we właściwości Parent obiektu myEditor.
- Kod: Zaznacz cały
myEditor = new TComboBox(Owner);
myEditor->Parent = this;
myEditor->Visible = FALSE;
myEditor->Style = csDropDown;
myEditor->OnChange = myEditorChange;
Zasadniczo to powinna ona mieć za 'rodzica' (Parent) obiekt StringGrid, a nie jak podałem okno formularza (this). Jednak nie może tak być o czym w drugim sposobie.
Możesz zrobić to na dwa sposoby. Ustawiasz jako rodzica zakładkę TabSheet na której znajduje się StringGrid:
- Kod: Zaznacz cały
myEditor = new TComboBox(Owner);
myEditor->Parent = TabSheet1;
myEditor->Visible = FALSE;
myEditor->Style = csDropDown;
myEditor->OnChange = myEditorChange;
ale musisz również zmodyfikować położenie myEdytor względem StringGrid:
- Kod: Zaznacz cały
void __fastcall TForm1::MoveEditor(void)
{
TRect Rect = StringGrid1->CellRect(StringGrid1->Col, StringGrid1->Row);
myEditor->Visible = FALSE;
myEditor->Top = PageControl1->Top + TabSheet1->Top + StringGrid1->Top + Rect.Top + StringGrid1->GridLineWidth;
myEditor->Left = PageControl1->Left+ TabSheet1->Left + StringGrid1->Left + Rect.Left + StringGrid1->GridLineWidth;
myEditor->Height = (Rect.Bottom - Rect.Top) + 1;
myEditor->Width = (Rect.Right - Rect.Left) + 1;
myEditor->Visible = TRUE;
}
Drugi sposób to ustawiasz jako rodzica obiekt StringGrid1, ale przy takim ustawieniu mimo iż będziesz wybierał z listy ComboBox jakiś element to nie będzie on wstawiany do komórki obiektu StringGrid co ma chyba jakiś związek z dziedziczeniem zdarzeń. Mogę się mylić co do tego dziedziczenia jednak nie mylę się co do tego, że ustawienie obiektowi myEditor za rodzica obiektu StringGrid spowoduje, że to nie będzie działać.
Problem można obejść. W tym celu trzeba 'powołać do życia' dodatkowy obiekt dynamicznie tworzony typu TPanel. Tak utworzonemu panelowi - nazwijmy go myPanel przypisujemy jako rodzica obiekt StringGrid, a obiektowi myEditor przypisujemy jako rodzica obiekt myPanel i teraz to będzie działać.
Co więcej nie będzie już miało znaczenia gdzie (na jakim obiekcie) będzie znajdował się StringGrid, lista będzie wyświetlana we właściwej pozycji.
Podaję gotowy kod:W pliku nagłówkowym np. Unit1.h:
- Kod: Zaznacz cały
private: // User declarations
TComboBox *myEditor;
TPanel *myPanel;
void __fastcall myEditorChange(TObject *Sender);
void __fastcall MoveEditor(void);
TStringList *Lista;
W pliku źródłowym np. Unit1.cpp:
- Kod: Zaznacz cały
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Lista = new TStringList;
Lista->LoadFromFile(ExtractFilePath(ParamStr(0)) + "lista.txt");
myPanel = new TPanel(this);
myPanel->Parent = StringGrid1;
myPanel->Visible = false;
myPanel->BevelOuter = bvNone;
myPanel->Ctl3D = false;
myPanel->ParentBackground = false;
myPanel->ParentColor = false;
myPanel->Color = clWhite;
myPanel->Caption = "";
myEditor = new TComboBox(myPanel->Handle);
myEditor->Parent = myPanel;
myEditor->Left = 0;
myEditor->Top = 0;
myEditor->Style = csDropDownList;
myEditor->OnChange = myEditorChange;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::myEditorChange(TObject *Sender)
{
StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row]
= myEditor->Items->Strings[myEditor->ItemIndex];
myPanel->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MoveEditor(void)
{
TRect Rect = StringGrid1->CellRect(StringGrid1->Col, StringGrid1->Row);
int gWidth = StringGrid1->GridLineWidth;
myPanel->Visible = false;
myPanel->Top = Rect.Top + gWidth;
myPanel->Left = Rect.Left + gWidth;
myPanel->Height = (Rect.Bottom - Rect.Top) + 1;
myPanel->Width = (Rect.Right - Rect.Left) + 1;
myEditor->Width = myPanel->Width;
myEditor->Height = myPanel->Height;
myPanel->Visible = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1Click(TObject *Sender)
{
if(StringGrid1->Col >= 2 && StringGrid1->Col <= 3)
{
myEditor->Items->Clear();
myEditor->Items = Lista;
MoveEditor();
myEditor->DroppedDown = true;
}
}
//---------------------------------------------------------------------------
Mała uwaga do tego fragmentu kodu:
- Kod: Zaznacz cały
myPanel->ParentBackground = false;
Jeżeli używasz starszej wersji środowiska to obiekt typu TPanel nie ma właściwości
ParentBackground i musisz usunąć ten fragment kodu.