Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Проблемы Циклического Обхода Компонентов в TabSheet на Delphi

Delphi , Компоненты и Классы , Компоненты

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

Описание Проблемы

Разработчик столкнулся с проблемой, когда попытка обхода компонентов на вкладке TabSheet (Tab) в объекте TabSheet не давала ожидаемого результата. Несмотря на то, что проверка на активную вкладку осуществлялась успешно, количество компонентов на вкладке определялось как ноль, хотя на вкладке находились два панели с общим количеством девяти чекбоксов.

Анализ Кода

В коде, представленном разработчиком, используется свойство Components для обхода компонентов активной вкладки. Однако, в Delphi, свойство Components содержит компоненты, которые являются владельцами активной вкладки, а не ее дочерними элементами. В случае, если компоненты были добавлены в визуальном редакторе, то владельцем этих компонентов является сама форма, а не вкладка TabSheet.

Подтвержденное Решение

Для корректного обхода дочерних элементов вкладки TabSheet необходимо использовать свойство Controls вместо Components. Вместо ComponentCount следует использовать ControlCount. Обход должен осуществляться через массив Controls[].

Кроме того, учитывая, что на вкладках могут быть панели с чекбоксами в качестве дочерних элементов, потребуется рекурсивный обход, чтобы включить все дочерние элементы, независимо от уровня вложенности.

Пример кода, который решает проблему:

procedure TfrmHsUsers.pagUsersClick(Sender: TObject);
var
  i, j: Integer;
  Fieldname: string;
  CheckBox: TcxDbCheckBox;
  Panel: TPanels;
begin
  if pagUsers.Properties.ActivePage.Name = 'tabProgram' then
  begin
    // Обход всех дочерних элементов активной вкладки
    for i := 0 to pagUsers.Properties.ActivePage.ControlCount - 1 do
    begin
      if (pagUsers.Properties.ActivePage.Controls[i] is TPanels) then
      begin
        // Нашли панель, обходим ее дочерние элементы
        Panel := TPanels(pagUsers.Properties.ActivePage.Controls[i]);
        for j := 0 to Panel.ControlCount - 1 do
        begin
          if (Panel.Controls[j] is TcxDbCheckBox) then
          begin
            CheckBox := TcxDbCheckBox(Panel.Controls[j]);
            Fieldname := CheckBox.DataBinding.DataField;
            CheckBox.Enabled := Settings.License.IsEnabled(Fieldname);
          end;
        end;
      end
      else if (pagUsers.Properties.ActivePage.Controls[i] is TcxDbCheckBox) then
      begin
        CheckBox := TcxDbCheckBox(pagUsers.Properties.ActivePage.Controls[i]);
        Fieldname := CheckBox.DataBinding.DataField;
        CheckBox.Enabled := Settings.License.IsEnabled(Fieldname);
      end;
    end;
  end;
end;

В данном примере используется проверка типов для каждого дочернего элемента вкладки, и если элемент является панелью или чекбоксом, выполняется соответствующая логика.

Альтернативный Подход

Для упрощения кода и уменьшения количества проверок типов можно использовать перечисление, как показано в альтернативном ответе:

uses
  System.SysUtils;

type
  TTabSheetEnumerator<T> = TEnumerator<T>;

  TTabSheetEnumerator<T>.Create = function(AControl: TControl): TEnumerator<T>;
  begin
    Result := TEnumerator<T>.Create(AControl, function(const C: TControl): Boolean;
      Result := TControl(T).FindControl<T>(AControl, True) <> nil
    );
  end;

var
  CheckBox: TcxDbCheckBox;
begin
  if pagUsers.Properties.ActivePage.Name = 'tabProgram' then
  begin
    for CheckBox in TTabSheetEnumerator<TcxDbCheckBox>.Create(pagUsers.Properties.ActivePage) do
    begin
      Fieldname := CheckBox.DataBinding.DataField;
      CheckBox.Enabled := Settings.License.IsEnabled(Fieldname);
    end;
  end;
end;

Данный подход позволяет более лаконично обойти все чекбоксы на вкладке, включая те, которые находятся на панелях.

Заключение

При работе с TabSheet в Delphi важно помнить, что для обхода дочерних элементов следует использовать свойства Controls и ControlCount, а не Components и ComponentCount. При необходимости использования вложенных элементов потребуется дополнительный обход дочерних компонентов панелей. Приведенные примеры кода демонстрируют, как можно решить данную проблему, используя стандартные возможности языка Object Pascal.

Создано по материалам из источника по ссылке.

Проблема заключается в некорректном обходе компонентов на вкладке TabSheet в Delphi из-за неправильного использования свойств для доступа к дочерним элементам.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Компоненты ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-16 03:43:51/0.0037720203399658/0