Как в Delphi создать класс, производный от класса TStringGrid, чтобы массив TObject, связанный с ячейками сетки, имел более конкретный тип, например TColor, который будет использоваться для указания цвета ячейки?
Создание класса TStringGrid в delphi, где массив объектов, связанный с ячейками, указан как более конкретный тип
Ответы (2)
TStringGrid может содержать TObject для каждой ячейки. TColor не наследуется от TObject, поэтому он не работает.
Вы можете привести TColor к TObject, но это будет плохим решением, подверженным проблемам в будущем. И это не будет работать для любого типа (только для тех, у которых размер не больше указателя).
Лучшее решение — поместить ваши данные в TObject и сохранить экземпляр такого объекта в StringGrid.
TMyBoxingColorObject = class
Data : TColor; // Or any other datatype
end;
Не забудьте создать и освободить объект по мере необходимости!
Вы также можете использовать дженерики, если у вас есть много разных типов для упаковки.
person
fpiette
schedule
05.02.2021
склонен к проблемам в будущем — только если Delphi когда-нибудь снова заставит
TObject
использовать ARC. Что, учитывая отказ Embarcadero от этой функции в версии 10.4, вряд ли повторится в ближайшее время, если вообще произойдет. Лучшее решение — упаковать данные. Проблема с упаковкой заключается в том, что вы являетесь владельцем. Кому принадлежат объекты-коробки и кто должен их освобождать? TStringGrid
недостаточно виртуален, чтобы надежно делать это исключительно в потомке, возлагая нагрузку на пользователя и вообще сводя на нет цель создания потомка.
- person Remy Lebeau; 05.02.2021
Я бы сказал, что в Delphi довольно идиоматично использовать
Tag
, (элемент представления списка) Data
, Objects[i]
и т. д. для хранения всего, что помещается в целое число собственного размера. (Кроме того, утверждение, что TColor не наследуется от TObject, немного вводит в заблуждение, поскольку TColor не наследуется ни от чего.) Тем не менее, ваше предложение прекрасно, если вам нужно хранить больше данных, чем вы можете поместить в целое число собственного размера. .
- person Andreas Rejbrand; 05.02.2021
Я надеюсь, что когда-то созданный, следующий grid.Objects[c,r]. будет знать, что я имею в виду объект типа TColor и что когда я набираю точку, я получаю параметры, связанные с TColor. Это ожидаемое поведение?
- person Tony Wolff; 05.02.2021
@TonyWolff нет, это не так
- person Remy Lebeau; 05.02.2021
Тони, если вы хотите этого, без использования приведения, вы должны создать новый класс из TStringGrid (или пользовательский) и предоставить новое свойство надлежащего типа бокса. Лично я успешно использую класс бокса и использую приведение: TMyBoxingColorObject(MyStringGrid.Objects[Col, Row]). Затем, если вы добавите точку, Delphi покажет доступные элементы. В зависимости от вашего вкуса также может быть полезен класс интерпозера.
- person fpiette; 05.02.2021
person
schedule
Как я уже сказал в своем ответе, это правильно только для данных, имеющих тот же размер, что и указатель. ОП сказал, что TColor был просто примером.
- person fpiette; 05.02.2021
@fpiette отлично работает для типов до размера указателя, они могут быть меньше. Например, в 32-битной системе Int64 не будет работать. Кроме того, особое внимание следует уделить типам с подсчетом ссылок, таким как строки и интерфейсы. Но это всего лишь один пример того, как реализовать пользовательское свойство для работы с типом, отличным от TObject.
- person Remy Lebeau; 05.02.2021
TColor
не является классом и, следовательно, не принадлежит ни к какой иерархии классов.TColor
неTObject
. Однако так получилось, чтоTColor
является 32-битным целым числом и поэтому подходит для переменнойTObject
(=указатель) на всех используемых сегодня платформах (32-битных и 64-битных). ОднакоTButton
,TBitmap
иTStringList
являются классами, поэтому экземплярTStringList
являетсяTObject
. - person Andreas Rejbrand   schedule 05.02.2021