Delphi 3. Библиотека программиста

       

Использование данных


Цель любого пользовательского интерфейса — организация эффективного взаимодействия с пользователем. Пользователь должен видеть достаточно данных, чтобы принять и реализовать решение (или по крайней мере понять, что на основании представленных данных это сделать невозможно). В графических деревьях объект удобно выбирать двойным щелчком или клавишей «пробел».

После того как пользователь выберет какой-либо объект, ваше приложение должно идентифицировать его. Текст, отображаемый в элементе, не всегда однозначно определяет объект (он может повторяться в других объектах), поэтому каждый объект обычно снабжается уникальным идентификатором. Такие идентификаторы должны быть короткими, чаще всего— числовыми. Чтобы обеспечить уникальность нового идентификатора, достаточно прибавить 1 к максимальному существующему значению.

Замечание

Хотя мы используем свойство Index для организации иерархии в элементе, это вовсе не означает, что оно остается постоянным для каждого объекта. Свойство Index класса TOutline изменяется при каждом изменении содержимого TOutline; это относительное значение, не связанное с конкретными объектами.

Идентификатор связывается с самим объектом. В дальнейшем по нему можно узнать, какой объект выбрал пользователь. В большинстве элементов, содержащих строковые объекты, также хранятся и связанные со строками объектные указатели. Эта часть интерфейса TString используется многими элементами. Вы можете сохранить указатель на любой объект или просто значение, похожее на указатель. Можно взять положительное целое число (тип данных cardinal), преобразовать его в TObject и сохранить в этом свойстве (обычно оно называется Objects). Если идентификатор не является целочисленным значением, придется создать специальный класс для хранения данных:

type TMyClass = class(TObject) public ID : String; end; begin ... NewIDObject := TMyClass.Create; NewIDObject.ID :=ItemTable.FieldByName ('ID').AsString; MyOutline.AddChildObject(0, ItemTable.FieldByName('Description').AsString, NewIDObject);

В компоненте TOutline эти указатели можно получить через Items[Index].Data, вместо того чтобы обращаться к свойству Objects, как это делается в большинстве элементов (и еще одно отклонение от нормы: значения Index начинаются с 1, а не с 0, как в большинстве списков). Указатель связывает объект, порожденный от TObject (то есть экземпляр любого класса), с объектом иерархии. Вам придется определить новый класс для хранения идентификатора, а затем создавать экземпляр этого класса для каждого загружаемого объекта, заносить в него идентификатор и правильно устанавливать указатель.

Чтобы добраться до идентификатора, можно воспользоваться следующим фрагментом кода:

with MyOutline do ThisID := (Items[SelectedItem].Data as TMyIDClass).ID;

Возможно, вашему приложению будет недостаточно одного идентификатора и потребуется дополнительная информация. По значению идентификатора можно найти нужную информацию в таблице. Кроме того, можно расширить определение TMyIDClass и сохранять дополнительную информацию в самих объектах.

Помните, что свойство Objects или Data не будет автоматически уничтожать эти объекты. Поэтому либо сделайте их потомками TComponent, чтобы их мог уничтожить владелец компонента, либо переберите элементы списка в деструкторе или обработчике FormDestroy и уничтожьте их самостоятельно. Если вы корректно используете свойство Count, в одном фрагменте кода можно спокойно уничтожать объекты, которые были (или не были) созданы в другом фрагменте.

with MyOutline do for Counter := Count downto 1 do (Items[Counter].Data as TMyIDClass).Free;

Обратите внимание на то, что в этом фрагменте уничтожение объектов в порядке «снизу вверх» в цикле for..downto оказывается чуть более эффектив ным, потому что списку при этом не приходится перемещать объекты для заполнения пустых мест.



Содержание раздела