#delphi
#delphi
Вопрос:
Я сохраняю свойства элементов управления ‘visible’ и ‘enabled’ в таблице БД. В зависимости от роли пользователя я делаю некоторые элементы управления невидимыми / включенными.
поля таблицы БД «Элементы управления»: id, role_id, form (varchar), comp_name (varchar), visible (логическое значение), enable (логическое значение)
запрос qControls: select * from controls where form=:form
вызов этой процедуры из OnShow основной формы:
application.CreateForm(TForm1, Form1);
FORM := 'Form1';
Form1.showModal;
Вызываемая процедура:
procedure RightsOnControls();
var i:integer;
begin
fMain.qControls.Close;
fMain.qControls.Params[0].AsString:= FORM; //FORM is global variable: FORM:='Form1'
fMain.qControls.Open;
if fMain.qControls.RecordCount>0 then begin
while not fMain.Controls.Eof do begin
for I := 0 to form1.ControlCount - 1 do
if uppercase(form1.Controls[i].Name)= uppercase(fMain.qControlsComp_name.AsString) then
begin
form1.Controls[i].Visible:=fmain.qControlsVisible.AsBoolean;
form1.Controls[i].Enabled:=fmain.qControlsEnable.AsBoolean;
end;
fMain.qControls.next;
end;
end;
end;
Мои вопросы:
- как сделать процедуру общим обработчиком событий, а не только для Form1?
- Он находит только элементы управления, расположенные в форме, а не элементы управления, расположенные на панели / элементе управления страницей (tabsheet). Как это изменить?
Ответ №1:
Вызовите эту процедуру с формой для обработки (например, form1) и запросом (fMain.qControls):
procedure RightsOnControls(AForm: TForm; AQuery: TFDQuery);
function FindChildControl(Parent: TWinControl; const ControlName: string): TControl;
var
I: Integer;
begin
for I := 0 to Parent.ControlCount - 1 do begin
Result := Parent.Controls[I];
if SameText(Result.Name, ControlName) then Exit;
if Result is TWinControl then begin
Result := FindChildControl(TWinControl(Result), ControlName);
if Result <> nil then Exit;
end;
end;
Result := nil;
end;
var
ctl: TControl;
begin
AQuery.Close;
AQuery.Params[0].AsString := AForm.Name;
AQuery.Open;
while not AQuery.Eof do begin
ctl := FindChildControl(AForm, AQuery.FieldByName('Comp_name').AsString);
if ctl <> nil then begin
ctl.Visible := AQuery.FieldByName('Visible').AsBoolean;
ctl.Enabled := AQuery.FieldByName('Enable').AsBoolean;
end;
AQuery.next;
end;
end;
Если вы не используете FireDAC, измените тип запроса на любой подходящий.
Комментарии:
1. Уве Раабе, спасибо, что потратил время и усилия на написание этого кода Ваш код частично решил мою проблему — он работает для любой формы, но FindChildControl не находит элементы управления, которые расположены на панели / pagecontrol (tabsheets).
2. Я добавил рекурсивную реализацию FindChildControl .
3. Уве Раабе, результат := FindChildControl(результат, ИмяконтРоля) вызывает ошибку: «Несовместимые типы WinControl и TControl», поскольку результатом является TControl, а не TWinnControl.
4. Уве Раабе, отличная работа!!! Ты лучший. Это работает без каких-либо исключений. У меня есть pagecontrol, на котором расположены другие элементы управления страницами, которые содержат таблицы, а на таблицах расположена панель, а на ней находятся элементы управления (кнопки, редактирование и т. Д.). Он находит все эти элементы управления! Большое вам спасибо.