Компонент VCL новичок здесь, так что извините, если это глупый вопрос …
Я пытаюсь сделать компонент TComboBox с элементами по умолчанию в нем после его перетаскивания на форму, то есть TMonthComboBox, который будет иметь список месяцев в своем списке элементов при его перетаскивании на форму.
Я обнаружил, что попытка получить доступ к свойству Items во время строительства приведет к «Control » не имеет родительского окна«ошибка, если я попытаюсь сбросить такой комбобокс на форму.
вот (часть) конструктор:
__fastcall TMonthCombo::TMonthCombo(TComponent *Owner):TComboBox(Owner)
{
this->Style = csDropDownList; // this is okay
this->Items->Add("January"); // This is causing problem
}
Я понял, что проблема связана с тем фактом, что свойство Items еще не доступно на данном этапе построения.
В любом случае можно ли быть уверенным, что компонент готов принимать значения в свойстве Items, в самом исходном коде компонента (т.е. не добавлять элементы списка в редакторе свойств во время разработки)?
Прежде чем кто-нибудь скажет мне «Просто добавьте элементы в код приложения во время выполнения», я должен объяснить, что этот ComboBox будет использоваться довольно часто во многих местах, и выбор месяца — это простой пример, который я использовал для объяснения проблемы, Фактические значения, которые я хочу поместить в ComboBox, гораздо более разнообразны и в большинстве случаев носят динамический характер. Он также должен реагировать на выбор пользователя различными способами.
Я пробовал способ выполнения, но он становится очень утомительным. Вот почему я превращаю его в компонент, чтобы он справлялся сам, без необходимости многократно вводить несколько версий кодов только для заполнения ComboBox.
Спасибо за любую помощь.
Изменить: После пробного решения Manlio ComboBox выглядит странно во время выполнения:
ComboBox имеет двойное изображение во время выполнения. Что я сделал не так?
__fastcall TYearCombo::TYearCombo(TComponent* Owner) : TComboBox(Owner), init_items(true)
{
}
//---------------------------------------------------------------------------
void __fastcall TYearCombo::CreateWnd()
{
unsigned short yr, mn, dy;
this->Width = 90;
this->Style = csDropDownList;
this->DropDownCount = 11;
TDate d = Today();
d.DecodeDate(&yr, &mn, &dy);
year = yr;
if (init_items)
{
init_items = false;
TComboBox::CreateWnd();
Items->BeginUpdate();
for(int i=year-5; i<=year+5; i++)
{
Items->Add(IntToStr(i));
}
this->ItemIndex = 5;
Items->EndUpdate();
}
}
//---------------------------------------------------------------------------
Вы можете попробовать это:
Переопределить CreateWnd
виртуальный метод и добавить init_items
личный член данных:
class TMonthCombo : public TComboBox
{
// ...
protected:
virtual void __fastcall CreateWnd();
private:
bool init_items;
// ...
};
Установить init_items
флаг:
TMonthCombo::TMonthCombo(TComponent *Owner) : TComboBox(Owner),
init_items(true)
{
// ...
}
внутри CreateWnd
Вы можете добавить новые предметы:
void __fastcall TMonthCombo::CreateWnd()
{
TComboBox::CreateWnd();
if (init_items)
{
init_items = false;
Items->BeginUpdate();
Items->Add("January");
// ...
Items->EndUpdate();
}
}
Дальнейшие заметки:
TComboBox
требует выделенного HWND
для того, чтобы хранить строки в его Items
имущество).просто бросить конструктора Owner
параметр для TWinControl
и назначить результат для компонента Parent
имущество не решение:
TMonthCombo::TMonthCombo(TComponent *Owner) : TComBoBox(Owner)
{
Parent = static_cast<TWinControl *>(Owner);
// ...
}
назначение решает «Элемент управления не имеет ошибки родительского окна» но создает другую проблему: форма всегда является родителем компонента (вы не можете добавить форму в другой контейнер).