Форум: "Основная";
Текущий архив: 2002.11.04;
Скачать: [xml.tar.bz2];
ВнизВопрос по динамическому созданию TComboBox ов. Найти похожие ветки
← →
Дельфятник (2002-10-18 17:01) [0]Я хочу на TStringGrid, лежающую на TGroupBox"е, помещать TComboBox"ы в каждую строчку в определённую ячейку. Вот как я пытаюсь это сделать:
procedure TForm1.BitBtn1Click(Sender: TObject);
var x: TComboBox;
r: TRect;
begin
...
StringGrid1.RowCount:=2;
...
with StringGrid1 do
begin
Query1.First;
repeat
...
Cells[0,RowCount-1]:=IntToStr(RowCount-1); // порядковый номер строки
...
x:=TComboBox.Create(StringGrid1);
r:=CellRect(3,RowCount-1); // это я пытаюсь поместить этот TComboBox в 4-й столбец
x.Top:=r.Top+1;
x.Left:=r.Left+2;
x.Width:=20;
// SendMessage(x.Handle,CB_SETDROPPEDWIDTH,300,0);
x.DropDownCount:=15;
RowCount:=RowCount+1;
...
Query1.Next;
until Query1.Eof;
RowCount:=RowCount-1
end;
...
end;
В результате не видно ни одного TComboBox"a. Пробовал пременную x делать глобальной - не помогло. Пробовал x:=TComboBox.Create(Form1) - тоже не помогло. Как это надо делать?
← →
MBo (2002-10-18 17:05) [1]в FAQ
← →
Orc (2002-10-18 17:05) [2]Поставь x.parent := StringGrid1;
← →
MBo (2002-10-18 17:19) [3]>Orc
НЕ НАДО!!!
форму парентом назначить нужно
← →
Дельфятник (2002-10-18 17:22) [4]Спасибо всем - посмотрел в FAQ ( http://delphi.mastak.ru/cgi-bin/faq.pl?look=1&id=988625051&n=19), поставил x.parent:=StringGrid1; и TComboBox"ы стали видны. Но что плохо, так это то, что они все почему-то образуются в видимой части TstringGrid"a, а в невилимой их почему-то нет. Как их туда засунуть?
← →
MBo (2002-10-18 17:25) [5]Нужно только один ComboBox, показывай его в OnSelectCell
← →
han_malign (2002-10-18 17:34) [6]фильтровать не стал смотри обьекты с префиксом cb...
суть в чем:
если отрисовывать все ComboBox-ы(CB) будут жуткие тормоза, поэтому
в обычном режиме отрисовывается текст с текущим состоянием, при фокусе на ячейку с CB в него загружается состояние элемента, он позиционируется на ячейку и показывается. При этом диалог не загроможден лишними эламентами управления, элемент управления создается только один раз и работает все гораздо быстрее(я с начала от начальника отбивался, потом посмотрел - действительно симпатично).
З.Ы. Так же с любым контролом, в этой задаче у меня еще и слайдер отрисовался, но по настоянию начальника пришлось заменить на CB, для единообразия.
это TDrawGrid
procedure TPlaySelectForm.dgChannelsDrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
if(ARow=0)then begin
DrawText(locs[locsChanNumber+ACol],ACol,ARow,Rect,dgChannels.Canvas);
end else begin
if((gdSelected in State)and(ACol>0))then begin
if(ARow<(dgChannels.RowCount-1))then begin
F_fProper:=true;
case ACol of
1: begin
CheckDeviceBox(ARow-1);//заносит в CB состояние элемента
cbDevice.SetBounds(Rect.Left+2,Rect.Top+2,Rect.Right-Rect.Left,Rect.Bottom-Rect.Top);
cbDevice.Visible:=true;
end;
2: begin
cbBalance.ItemIndex:=F_paChannels[ARow-1].Balance;//заносит в CB состояние элемента
cbBalance.SetBounds(Rect.Left+2,Rect.Top+2,Rect.Right-Rect.Left,Rect.Bottom-Rect.Top);
cbBalance.Visible:=true;
//тут была заморочка с сохранинием фокуса на одном из двух CB при движениии вверх вниз с клавы
if(F_fBalanceSetFocus)then cbBalance.SetFocus
else if(not F_fBalanceFocused)then cbDevice.SetFocus;
F_fBalanceSetFocus:=false;
end;
end;
F_fProper:=false;
end else begin
//отрисовка при выделении титула (ни одной активной рабочей ячейки)
if(cbDevice.Visible)then dgChannels.SetFocus;
cbDevice.Visible:=false;
cbBalance.Visible:=false;
end;
end else begin
if(ARow<(dgChannels.RowCount-1))
then F_paChannels[ARow-1].Draw(ACol,ARow,Rect,dgChannels.Canvas);
end;
end;
end;
← →
MBo (2002-10-18 17:37) [7]http://delphi.mastak.ru/cgi-bin/faq.pl?look=1&id=988624800&n=17
← →
MegaVolt (2002-10-22 15:03) [8]выше приведённой ссылке есть рецепт как сделать один контрол в выделенной ячейке а нужно в кажстроке комбобоксы. Как это можно сделать?
← →
MBo (2002-10-22 15:11) [9]Зачем? Они же не используются одновременно
← →
MegaVolt (2002-10-22 16:03) [10]Но очень бы хотелось чтобы они были видны (их состояние) во всех видимых строчках. Например как в CheckListBox
← →
MegaVolt (2002-10-22 17:11) [11]Я нашол как это сделать :) Хорошо что в дельфях есть исходники:
DrawFrameControl позволяет рисовать контролы нажатый и отжатый. По событию OnDrawCell рисуем то что нам нужно а по On MauseUp (или Down) изменяем :)
← →
Дельфятник (2002-10-22 18:12) [12]А я сделал по-другому.
В коде, содержащемся в первом сообщении я изменил цикл repeat .. until следующим образом:
var x: TComboBox;
y: Boolean;
i,j: Word;
...
repeat
if (RowCount=2) or (Cells[1,RowCount-2]<>Query1RUS4.AsString) then
begin
y:=False; j:=0;
Cells[0,RowCount-1]:=IntToStr(RowCount-1);
...
for i:=0 to Form1.ControlCount-1 do if (Form1.Controls[i] is TComboBox)
and ((Form1.Controls[i] as TComboBox).Name="ComboBox"+IntToStr(RowCount-1))
then begin
y:=True; j:=i // если TComboBox c таким именем уже есть, то запоминаем его номер
end;
if not y then // а если нет, то создаём такой ComboBox
begin
x:=TComboBox.Create(Form1);
x.Name:="ComboBox"+IntToStr(RowCount-1);
x.Parent:=Form1;
x.Width:=75;
x.Tag:=RowCount-1;
x.DropDownCount:=20;
x.Items.Add(Query1CODE.AsString);
x.Style:=csDropDownList;
x.ShowHint:=True;
x.OnClick:=ComboBox0.OnClick; // ComboBox0 создан в design-time
x.OnEnter:=ComboBox0.OnEnter;
x.OnKeyPress:=ComboBox0.OnKeyPress;
Hint:=IntToStr(x.Items.Count);
Objects[3,RowCount-1]:=x // устанавливаю связь ячейки с TComboBox"ом
end
else with Form1.Controls[j] as TComboBox do
begin // этот ComboBox был создан в одно из предыдущих нажатий кнопки
Clear; // BitBtn1, поэтому его содержимое надо очистить
Items.Add(Query1CODE.AsString);
Hint:=IntToStr(Items.Count)
end;
RowCount:=RowCount+1
end
else with Objects[3,RowCount-2] as TComboBox do
begin // а это добавление Query1CODE в TComboBox на одну строчку выше
Items.Add(Query1CODE.AsString);
Hint:=IntToStr(Items.Count)
end;
Query1.Next
until Query1.Eof;
На событие StringGrid1.OnTopLeftChanged я повесил такой обработчик:
procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject);
var r: TRect;
i: Word;
begin
if StringGrid1.RowCount>1 then for i:=1 to StringGrid1.RowCount-1 do
begin
R:=StringGrid1.CellRect(3,i);
if StringGrid1.Objects[3,i] as TComboBox<>nil then with StringGrid1.Objects[3,i] as TComboBox do
begin
Left:=StringGrid1.Left+R.Left+2;
Top:=StringGrid1.Top+APGrid.Top+R.Top;
if Text="" then ItemIndex:=0;
Visible:=(R.Left>0) and (R.Top>0) // у невидимых в данный момент ячеек TStringGrid"a R.Left=0 и R.Top=0
end
end
end;
Этот самый StringGrid1TopLeftChanged вызывается после того цикла после нажатия на BitBtn1, по событию Form1.OnResize (ибо с изменением размеров формы в моём случае происходит изменение размеров TStringGrid"ы и невилимые ранее ячейки могут оказаться видимыми и наоборот), а также по событиям StringGrid1.OnMouseUp и StringGrid1.OnMouseDown я определяю изменение левой координаты столбца с TComboBox"ами и изменение ширины этого столбца - для растягивания TComboBox"ов на всю длину ячейки.
Вот.
← →
MegaVolt (2002-10-23 09:48) [13]И что это всё не тормозит при количестве строк скажем 10000? Я пробовал делать ComboBox-ы в рунтайме и всё это достаточно тормозило во время заполнения. А вот если их просто рисовать DrawFrameControl то получается достаточно быстро. Кстати так же сделано и в CheckListBox
← →
Дельфятник (2002-10-23 09:58) [14]У меня нет такого количества строк (10000). Пока это не более 100. Это список международных аэропортов в РФ. Я думаю, ещё не скоро их станет около 10000 :)
А вообще, наверное, Вы правы.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.11.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.63 c