Текущий архив: 2006.01.29;
Скачать: CL | DM;
Вниз
одинаковые значения свойств Найти похожие ветки
← →
Kerk © (2005-12-18 14:45) [0]Есть несколько форм. Компонентам на этих формах необходимо задать одинаковые значения некоторых свойств (например шрифт). Компоненты разные, формы тоже. Значения "единых" свойств могут меняться в рантайм. Вот сижу, думаю. Можно конечно вручную все это контролировать, но криво. Хотелось бы маленький framework. Идеи?
← →
Карелин Артем © (2005-12-18 14:58) [1]
for i := 0 to s.ComponentCount - 1 do
begin
if s.Components[i] is TSplitter then
begin
(s.Components[i] as TSplitter).Color := clBlack;
(s.Components[i] as TSplitter).Beveled := False;
end;
if s.Components[i] is TLabel then
begin
(s.Components[i] as TLabel).Transparent := true;
end;
end;
← →
Kerk © (2005-12-18 15:01) [2]Карелин Артем © (18.12.05 14:58) [1]
> Можно конечно вручную все это контролировать, но криво.
Хотя, наверно, можно написать наследника TForm, где производить такое изменение, при изменении "единого" свойства формы.
← →
Джо © (2005-12-20 18:35) [3]
> [2] Kerk © (18.12.05 15:01)
Посмотри почту.
← →
Германн © (2005-12-21 02:13) [4]
> Kerk © (18.12.05 15:01) [2]
>
> Карелин Артем © (18.12.05 14:58) [1]
>
> > Можно конечно вручную все это контролировать, но криво.
>
>
> Хотя, наверно, можно написать наследника TForm, где производить
> такое изменение, при изменении "единого" свойства формы.
>
>
Можно, конечно и наследника. Но ты упомянул
> Значения "единых" свойств могут меняться в рантайм.
. А в рантайм, имхо, сойдет и процедура а-ля Карелин Артем © (18.12.05 14:58) [1] с параметромs: TForm
← →
Юрий Зотов © (2005-12-21 03:57) [5]Код [1] решает задачу, но если на каждой форме лежат штук хотя бы по 20 разных компонентов, то при таком подходе замучаешься писать код - этих IS и AS окажется слишком много. А между тем задачу можно решить в общем виде, без всяких IS и AS.
Делаем единую форму-предок, прочие наследуются от нее. На этой форме может вообще не лежать ни одного компонента, а могут и лежать - не важно. Важно лишь то, что у нее есть public-методы под названиями типа SetCommonFont. В методе SetCommonFont идет проход по компонентам формы, у каждого проверяется наличие свойства Font (через RTTI) и если оно есть, то ему ассигнуется нужное значение.
Все. Теперь можем в любой момент вызывать эти методы - свойства получат одинаковое значение.
← →
Джо © (2005-12-21 04:54) [6]Ладно, может кому еще пригодится, забрасываю юнит из своих старых грехов, немного подправил :)
unit PropSync;
interface
uses SysUtils, Classes, TypInfo, Contnrs, Forms;
type
TPropertiesSynchronizer = class
private
FFormClasses: TClassList;
procedure SynchronizeForm (AForm: TForm; AClass: TClass;
APropName: string; AValue: Variant);
function Registered (AForm: TForm): boolean;
public
procedure RegisterFormClass (AFormClass: TFormClass);
procedure Synchronize (AClass: TClass; APropertyName: string;
AValue: Variant);
constructor Create;
destructor Destroy; override;
end;
implementation
uses Variants;
{ TPropertiesSynchronizer }
constructor TPropertiesSynchronizer.Create;
begin
inherited Create;
FFormClasses := TClassList.Create;
end;
destructor TPropertiesSynchronizer.Destroy;
begin
FFormClasses.Free;
inherited;
end;
function TPropertiesSynchronizer.Registered(AForm: TForm): boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to FFormClasses.Count - 1 do
if FFormClasses[I] = AForm.ClassType then
begin
Result := True;
Break
end;
end;
procedure TPropertiesSynchronizer.RegisterFormClass(AFormClass: TFormClass);
begin
FFormClasses.Add(AFormClass)
end;
procedure TPropertiesSynchronizer.Synchronize (AClass: TClass;
APropertyName: string; AValue: Variant);
var
I: Integer;
begin
for I := 0 to Screen.FormCount - 1 do
if Registered(Screen.Forms[I]) then
begin
SynchronizeForm(Screen.Forms[I], AClass,
APropertyName, AValue);
end;
end;
procedure TPropertiesSynchronizer.SynchronizeForm(AForm: TForm;
AClass: TClass; APropName: string; AValue: Variant);
var
I: Integer;
Cmp: TComponent;
procedure _SetProp (AInstance: TObject);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo (AInstance, APropName);
if PropInfo <> nil then
case PropInfo.PropType^^.Kind of
tkClass:
SetObjectProp(AInstance,APropName,TObject(Integer(AValue)));
else
SetPropValue(AInstance,APropName,AValue);
end;
end;
begin
if AForm is AClass then
begin
_SetProp(AForm);
end;
for I := 0 to AForm.ComponentCount - 1 do
begin
Cmp := AForm.Components[I];
if Cmp is AClass then
_SetProp(Cmp);
end;
end;
end.
Пользование (предварительно создаем экз. объекта TPropertiesSynchronizer, разумеется).
МетодомRegisterFormClass
регистрирум КЛАССЫ форм, которые будем использовать:
FPropSync.RegisterFormClass(TForm1);
FPropSync.RegisterFormClass(TForm2);
// etc...
</CODE
Затем используем методSynchronize
. Например:
a)FPropSync.Synchronize(TEdit,"Text","The same text");
Одинаковый текст для всех наследников TEdit
b)FPropSync.Synchronize(TWinControl,"Color",clRed);
изменяет свойство Color := clRed для всех наследников TWinControl на всех существующих формах, чей класс был предварительно зарегистрирован при вызове RegisterFormClass.
c)FPropSync.Synchronize(TComponent,"Caption","The same caption");
Меняем Caption для всех наследников TComponent
d)FPropSync.Synchronize(TComponent,"Font",Integer(Label2.Font));
Делаем шрифт для всех наследников TComponent как у Label2
И так далее в таком духе.
← →
Джо © (2005-12-21 04:55) [7]Cорри за форматирование, забыл тэг закрыть.
← →
sniknik © (2005-12-21 08:59) [8]Юрий Зотов © (21.12.05 03:57) [5]
вот пример именно такой реализации 18-го вечером отправил ему по почте, но чегото молчит... не дошло чтоли.
кстати уточнение, пример конкретно для Font-а, неудачный... есть же свойство ParentFont, и у всех компонент по умолчанию оно true (ну почти у всех). достаточно следить чтобы оно таким (true) и оставалось, и менять фонт только у формы.
Страницы: 1 вся ветка
Текущий архив: 2006.01.29;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.043 c