Здравствуйте жители Королевства!
Возник такой вопрос:
Когда мы ставим на форму ComboBox и AutoDropDown=True то когда вводиш значение идет последовательно выбор из Items ComboBox -a. А когда заганяю Combobox в StirngGrid то этого выбора нет. (Вот код как ComboBox в StringGrid - е).
procedure TForm1.FormCreate(Sender: TObject);
begin
{Высоту combobox'а не изменишь, так что вместо combobox'а
будем изменять высоту строки grid'а !}
StringGrid1.DefaultRowHeight:=ComboBox1.Height; {Спрятать combobox}
ComboBox1.Visible:=False;
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
//Перебросим выбранное в значение из ComboBox в grid
StringGrid1.Cells[StringGrid1.Col,StringGrid1.Row]
:=ComboBox1.Items[ComboBox1.ItemIndex];
ComboBox1.Visible:=False;
StringGrid1.SetFocus;
end;
procedure TForm1.ComboBox1Exit(Sender: TObject);
begin
//Перебросим выбранное в значение из ComboBox в grid
StringGrid1.Cells[StringGrid1.Col,StringGrid1.Row]
:=ComboBox1.Items[ComboBox1.ItemIndex];
ComboBox1.Visible:=False;
StringGrid1.SetFocus;
end;
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
var
R: TRect;
begin
if ((ACol <> 1) and (ARow = 1)) then
begin
{Ширина и положение ComboBox должно соответствовать ячейке StringGrid}
R := StringGrid1.CellRect(ACol, ARow); R.Left := R.Left + StringGrid1.Left;
R.Right := R.Right + StringGrid1.Left; R.Top := R.Top + StringGrid1.Top;
R.Bottom := R.Bottom + StringGrid1.Top; ComboBox1.Left := R.Left + 1;
ComboBox1.Top := R.Top + 1; ComboBox1.Width := (R.Right + 1) - R.Left;
ComboBox1.Height := (R.Bottom + 1) - R.Top; {Покажем combobox}
ComboBox1.Visible := True; ComboBox1.SetFocus;
end;
CanSelect := True;
end;
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
16-05-2009 14:23 | Комментарий к предыдущим ответам
>>> Я не дал ссылку на описание метода Geo только потому, что Вы невнимательно смотрите на даты - мой ответ прозвучал в апреле 2008 года, а статья появилась только в июле того же года.
Я уже признал эту ошибку в сообщении от 31-10-2008 08:01
Не заметил, что вопрос старый... Статься была написана позже.
P.S. Прошу извинить, что сообшение от 31-10-2008 07:57 получилось в форме упрёка...
16-05-2009 12:20 | Комментарий к предыдущим ответам
2 Бел Амор:
Я не дал ссылку на описание метода Geo только потому, что Вы невнимательно смотрите на даты - мой ответ прозвучал в апреле 2008 года, а статья появилась только в июле того же года. Так что идинственный упрек - то, что я не указал, что это все-таки метод Geo. Этот упрек я признаю и обещаю исправиться. Кстати, метод различения нескольких экземпляров одного и того же класса по тегу имеется в обсуждениях указанной Вами статьи.
>>> Я сделал новые компоненты и добавил их на палитру, т.к. этот способ позволяет использовать и стандартный компонент на одной форме.
Программа - ваша, и принятие решения об использовании конкретных вариантов остаётся, естественно, за вами. Но я считаю, что добавление нового компонента в палитру только для формирования конкретного списка в одной конкретной TStringGrid - не очень удачное решение. Мой вариант с тегами - тоже решение "в лоб". Наилучшим вариантом, на мой взгляд, было бы либо создание универсального компонента, позволяющего формировать списки снаружи, либо перекрытие стандартной TStringGrid с добавлением такой возможности. Мне больше нравится второй вариант. Я попробовал это продемонстрировать. Некоторые вещи можно было сделать немного поудобнее, но пример вполне рабочий и пригодный для реального использования.
TStringGrid, которым не назначены списки, ничем не отличаются от стандартных, на форме можно использовать произвольное количество TStringGrid с разными списками или без списков.
{--------------------------------------------------------------}
{ Модуль StringGridWithPickList }
{ }
{ Перекрывает стандартный TStringGrid }
{ Добавляет возможность подключения выпадающих списков, }
{ назначаемых на ячейки по строкам или колонкам }
{ В uses должен указываться после модуля Grids }
{ Использован "Метод Geo": }
{ http://delphikingdom.com/asp/viewitem.asp?catalogid=1367 }
{--------------------------------------------------------------}
type
TPickListInfo = record
List: TStringList;
Row: Integer;
Col: Integer;
end;
TStringGrid=class(Grids.TStringGrid)
private
FPickLists: array of TPickListInfo;
function GetPickList(Idx: Integer): TStringList;
function GetPickListCol(Idx: Integer): Integer;
function GetPickListCount: Integer;
function GetPickListRow(Idx: Integer): Integer;
procedure SetPickListCol(Idx: Integer; const Value: Integer);
procedure SetPickListCount(const Value: Integer);
procedure SetPickListRow(Idx: Integer; const Value: Integer);
protected
function CreateEditor:TInplaceEdit; override;
function GetEditStyle(ACol,ARow:longint):TEditStyle ;override;
public
destructor Destroy; override;
property PickListCount: Integer read GetPickListCount write SetPickListCount;
property PickList[Idx: Integer]: TStringList read GetPickList;
property PickListCol[Idx: Integer]: Integer read GetPickListCol write SetPickListCol;
property PickListRow[Idx: Integer]: Integer read GetPickListRow write SetPickListRow;
end;
implementation
{Деструктор}
destructor TStringGrid.Destroy;
begin
PickListCount := 0;
inherited;
end;
{Перекрытые}
function TStringGrid.CreateEditor: TInplaceEdit;
begin
Result:=TInplaceEditList.Create(Self);
end;
function TStringGrid.GetEditStyle(ACol, ARow: Integer): TEditStyle;
var
i: Integer;
begin
Result := esSimple;
for i:=Low(FPickLists) to High(FPickLists) do
if (ACol = FPickLists[i].Col) or (ARow = FPickLists[i].Row) then
begin
Result := esPickList;
(InplaceEditor as TInplaceEditList).PickList.Items.Assign(FPickLists[i].List);
Exit;
end;
end;
{Свойства}
function TStringGrid.GetPickList(Idx: Integer): TStringList;
begin
Result := FPickLists[Idx].List;
end;
function TStringGrid.GetPickListCol(Idx: Integer): Integer;
begin
Result := FPickLists[Idx].Col;
end;
function TStringGrid.GetPickListCount: Integer;
begin
Result := Length(FPickLists);
end;
function TStringGrid.GetPickListRow(Idx: Integer): Integer;
begin
Result := FPickLists[Idx].Row;
end;
procedure TStringGrid.SetPickListCount(const Value: Integer);
var
i, OldValue: Integer;
begin
OldValue := PickListCount;
{Увеличение}
if OldValue < Value then
begin
SetLength(FPickLists, Value);
for i := OldValue to Value-1 do // Индексы с 0
with FPickLists[i] do
begin
List := TStringList.Create;
Row := -1;
Col := -1;
end;
end;
{Уменьшение}
if OldValue > Value then
begin
for i := OldValue-1 downto Value do // Индексы с 0
FPickLists[i].List.Free;
SetLength(FPickLists, Value);
end;
end;
To Бел Амор Спасибо за ответ! Я сделал новые компоненты и добавил их на палитру, т.к. этот способ позволяет использовать и стандартный компонент на одной форме.
>>> Подменяет "стандартные" функции TStringGrid и работать это будет только в Unit1.
Вы можете сделать несколько модулей с подменой TStringGrid и в разных модулях подключать нужный через uses
Но мне нужно получается сделать 2 потомка TStringGrid и в каждом отдельном подменить эти функции на новые, которые будут выставлять списки в каждом по-разному...
Если вам нужно в одном модуле сделать подмену для двух TStringGrid с разными списками, то в методе GetEditStyle класса TStringGrid вам нужно будет уметь различать экземпляры этого класса и для каждого формировать нужный список. Для того, чтобы экземпляры можно было различить, можно, например, использовать свойство Tag. Назначьте одному экземпляру, например, Tag=1, а дргому Tag=2 и проверяйте Tag в GetEditStyle
>>> Как можно сделать этих потомков визуальными? где это можно прочесть?
1. Не потомков, а потомка. Нужен один класс.
1. Он уже "визуальный". Вы не уловили, что подменяется один класс, и имя этого класса совпадает с исходным.
Рекомендую вынести доработанный класс в отдельный модуль и подключать в нужных местах через uses, иначе подменяться будут и все TStringGrid в модулях, использующих ваш модуль. Читайте статью.
To Python
Здравствуйте!
Долго искал ответ на вопрос который задал Юрий и нашел самый лучший здесь :)
Я пока совсем начинающий программист... и стоит такая задача. надо на форме сделать 2 TStringGrid со списками, причем позиции колонок со списками будут у этих TStringGrid -ов будут отличатся в первом это нужно сделать 0 строчку со списками, в во втором TStringGrid 2 колонку.
Как я понял вот эта часть кода:
Type TStringGrid=class(Grids.TStringGrid)
protected
function CreateEditor:TInplaceEdit;override;
function GetEditStyle(ACol,ARow:longint):TEditStyle;override;
end;
Подменяет "стандартные" функции TStringGrid и работать это будет только в Unit1.
Но мне нужно получается сделать 2 потомка TStringGrid и в каждом отдельном подменить эти функции на новые, которые будут выставлять списки в каждом по-разному...
Type TMyGrid1=class(Grids.TStringGrid)
protected
function CreateEditor:TInplaceEdit;override;
function GetEditStyle(ACol,ARow:longint):TEditStyle;override;
Type TMyGrid2=class(Grids.TStringGrid)
protected
function CreateEditor:TInplaceEdit;override;
function GetEditStyle(ACol,ARow:longint):TEditStyle;override;
end;
end;
Но беда в том, что пооложить эти TMyGrid1 и TMyGrid2 на форму нельзя (точнее я не знаю как это делать). Даже залез в dfm файл и совершил некоторые подуги... но испортил форму напроч :)
Как можно сделать этих потомков визуальными? где это можно прочесть?
Или может я черезчур замарачиваюсь?? и есть други пути решения этой маленькой, но для меня проблемы?
Спасибо!
Чего-то я не понимаю, зачем какой-то TComboBox привинчивать, если все уже привинчено. Как снаружи управлять - честно говоря, не знаю, но вот я слету написал такой простой пример, где можно выбирать значения и редактировать поля как душеньке угодно. На форме лежит TStringGrid, Align=alClient, Options=[goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goEditing, goAlwaysShowEditor] все остальное - по умолчанию, код
Type TStringGrid=class(Grids.TStringGrid)
protected
function CreateEditor:TInplaceEdit;override;
function GetEditStyle(ACol,ARow:longint):TEditStyle;override;
end;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TStringGrid }
{ TStringGrid }
function TStringGrid.CreateEditor: TInplaceEdit;
begin
Result:=TInplaceEditList.Create(Self);
with TInplaceEditList(Result) do begin
Parent:=Self.Parent;
end;
end;
function TStringGrid.GetEditStyle(ACol,ARow:longint):TEditStyle;
begin
case ACol of
1:begin
Result:=esPickList;
with TInplaceEditList(InplaceEditor) do begin
PickList.Clear;
PickList.AddItem('Column 1_1',nil);
PickList.AddItem('Column 1_2',nil);
PickList.AddItem('Column 1_3',nil);
PickList.AddItem('Column 1_4',nil);
end;
end;
2:begin
Result:=esPickList;
with TInplaceEditList(InplaceEditor) do begin
PickList.Clear;
PickList.AddItem('Column 2_1',nil);
PickList.AddItem('Column 2_2',nil);
PickList.AddItem('Column 2_3',nil);
PickList.AddItem('Column 2_4',nil);
end;
end else Result:=esSimple;
end;
end;
Вам указал на ошибку Александр Алексеев
Зачем Вам эта процедура:
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
//Перебросим выбранное в значение из ComboBox в grid
StringGrid1.Cells[StringGrid1.Col,StringGrid1.Row]
:=ComboBox1.Items[ComboBox1.ItemIndex];
ComboBox1.Visible:=False;
StringGrid1.SetFocus;
end;
При вводе любого символа в появившейся ComboBox получаете
скрытие (ComboBox1.Visible:=False) ComboBox'а.
Когда вы вводите что-то в ComboBox, у вас возникает OnChange. Что вы делаете в своём OnChange? Правильно, скрываете ComboBox.
И чего-же вы после этого ждали?
Ты хочеш сказать что содержимое Items в combobox забить в базу? Мне нужно чтобы випадал список при переходе в ячейку. Потом вынуть числа,(это будет масив), для работы с ними (мат. операциями). А GridPanel я что-то тоже не нашел.
А можешь сформулировать задачу, для каких целей понадобилось так мучаться? У меня была похожая задачка, но только с использованием базы данных, поэтому для моих целей подошел компонент DBGrid. Может тебе тоже он сможет помочь? Сейчас залезла в книжку по дельфи, там рассказывается про один интересный компонент GridPanel с вкладки Additional. Возможно тебе стоит поискать в этом направлении. Только я его у себя не нашла так сразу (у меня delphi7), не хватило немного времени разобраться. Может тебе это удастся.
Я хочу чтоби в Stringgrid - е был выпадающий список по-этому и ввожу туда Combobox. Делаю его невидимым чтобы он открывался тогда когда переходиш в ячейку где и есть Combobox. Сначала он начинает вылетать (по нажатию первой клавиши)(мышкой тоже можна выбрать), но потом - нажимая следующую клавишу начинает показывать в ячейке именно ее.
Пошагово пробывали пройтись по коду? Нет. Мне стыдно. я еще на слабом уровне и не понимаю принцыпа..
19-03-2008 10:13 | Вопрос к автору: запрос дополнительной информации
Не понятно, что значит "заганяю Combobox в StirngGrid"? И для каких целей? Может я не поняла вопроса, но судя по коду Combobox является невидимым, соответственно программа просто не заходит в его события. Пошагово пробывали пройтись по коду? Насколько я могла понять, то изменение всеже происходит в StrinGrid, а не в Combobox, соответственно происходит событие StrinGrid-а.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.