Мы часто пользуемся быстрым фильтром и привыкли к такой удобной функциональности. Но при работе в деревом такой функциональности нет.
Привожу пример, как, с моей точки зрения, возможна реализация функциональности быстрого фильтра в дереве. Это только один из возможных вариантов. Вы можете предложить большее.
Мельникова Екатерина на эту тему даже создала идею: community.terrasoft.ua/node/3032.
Главная идея - дерево может находится в двух режимах - дерево и список. При работе с деревом фильтрация невозможно. При работе со списком - мы можем осуществлять поиск нужной нам записи, и при переключении обратно в режим дерева мы позиционируемся на найденной записи.
Основа - режим переключения из дерева в список. В приведенном примере переключение между деревом и списком осуществляется по горячей клавише Ctrl-Q. Включение / отключение фильтра осуществляются по горячей клавише Ctrl-S.
Открываем окно с DataTreeGrid (в данном примере отображены все папки из директория "Program Files", Вы можете загрузить подобную структуру по кнопке "Загрузить папки из директория"):
Допустим, в дереве Вам необходимо найти библиотеку картинок программы Skype. В поле ввода быстрого фильтра набираем текст "Skype" и нажатием Ctrl-S включаем бытрый фильтр, который будет включен при переходе в режим отображения список.
Переключение просмотра в режим "Список" нажатием Ctrl-Q, после чего можно выбрать необходимую запись:
После того, как Вы нашли искомую запись - переключаемся в режим просмотра "Дерево" (Ctrl-Q):
Пример сервисов для работы быстрого фильтра в дереве Вы можете найти в присоединенном архиве TreeQuickFilter_Example.rar.
Основные моменты реализации:
Переключение режима "Дерево / Список" осуществляется подстановкой значения свойства "ParentDataFieldName" компонента DataTreeGrid поля "ParentID" если мы хотим видеть дерево или "ID", если нам нуже список (в данном случае возможно переключение без перезапроса данных в базе данных):
function SwitchTreeListViewType() {
var ParentDataFieldName = grdData.ParentDataFieldName;
if (ParentDataFieldName == 'ParentID') {
grdData.ParentDataFieldName = 'ID';
cbQuickFilter.IsEnabled = true;
} else {
grdData.ParentDataFieldName = 'ParentID';
cbQuickFilter.IsEnabled = false;
}
UpdateQuickFilter();
}
Выбор директория для загрузки в таблицу структуры папок:
function LoadFoldersFromDirectory() {
var FolderNameObject = System.CreateObject('TSObjectLibrary.Value');
if ((System.SelectDirectory("Выберите папку", '', FolderNameObject))) {
var FolderName = FolderNameObject.Value;
var Dataset = dlData.Dataset;
LoadDirectoryItemsFromFolder(FolderName, Dataset);
}
}
Загрузка структуры директория осуществляется с помощью рекурсивной функции:
function LoadDirectoryItemsToDataset(Path, Dataset, ParentID) {
try {
var Folder = FileSearchGridArea.FSO.GetFolder(Path);
var Folders = new Enumerator(Folder.SubFolders);
for (Folders.moveFirst(); !Folders.atEnd(); Folders.moveNext()) {
var Item = Folders.item();
var Name = Item.Name;
var Path = Item.Path;
var ID = AddFolderToDataset(Dataset, ParentID, Name, Path);
LoadDirectoryItemsToDataset(Path, Dataset, ID);
}
} catch(e) {
ShowErrorDialog(e.message);
}
}
Обработка горячих клавиш осуществляется в событии OnKeyDown DataTreeGrid:
function DoKeyDown(Control, Key, Shift) {
var CtrlDown = (Shift & 4) > 0;
if (CtrlDown) {
var QKeyCode = 81;
if (Key.Value == QKeyCode) {
SwitchTreeListViewType();
}
var SKeyCode = 83;
if (Key.Value == SKeyCode) {
cbQuickFilter.IsChecked = !cbQuickFilter.IsChecked;
}
}
}
Данный вариант работы с деревом имеет свои ограничения:
* Он быстро работает, когда количество записей не больше нескольких тысяч.
* Когда не используется режим подгрузки узлов дерева по требованию.
Конечно, реализовывать такое в конфигурации трудоемко, но можно. Лучшим решением было бы реализовать быстрый фильтр в ядре в компоненте DataTreeGrid.
Используйте на здоровье.