|
#1
|
||||
|
||||
Передать метод
Создавал не так давно тему по поводу передачи значения переменной в нужный TEdit.Text при ее (переменной) изменении.
Пришла мне в голову некоторая идея по этому поводу. А именно использовать не переменную, а экземпляр некоего класса. В это класс я закину компоненты, которые должны следить за нужной мне переменной (экземпляром класса). То есть не сами компоненты будут следить, а класс, при вызове метода Value будет изменять нужные компоненты. Код:
TMyClass = class private FValue:string function GetStr(index: string): string; procedure SetStr(index: string; const Value: string); public property Value:string read GetVal write SetVal; //кстати, хотелось бы сделать это свойство дефолтным, но // компилятор требует, чтобы оно было массивом, типа property Value[index:DataType]....... end; function TStr.GetStr: string; begin result:=FValue; end; procedure TStr.SetStr(const Value: string); begin FValue := Value; // Далее идет цикл, который перебирает выбранные мною компоненты и меняет нужное свойство на FValue // Но есть проблема. У TEdit'a это свойство Text, у TLabel - Caption и тд // А может, мне вообще потребуется менять свойство Hint или любое другое end; Вот теперь вопрос. Как мне оформить функцию для передачи компонента и record, хранящий информацию о компоненте так, чтобы вместе с самим компонентом программист так же передал нужное свойство для изменения? Код:
TComp = record Component:TComponent; Value:{здесь должно быть что то, ссылающееся на нужное свойство компонента} end; TComps = array of TComp; TMyClass = class private ***** FComps:TComps; public **** procedure AddComponent(C: TComponent;Prop: {должно передаться нужное свойство}); end; *** procedure AddComponent(C: TComponent;Prop:???); begin SetLength(FComps,Length(fcomps)+1); FComps[High(FComps)].Component := C; FComps[High(FComps)].Value := Prop; {тут должна передаться ссылка (или что там) на нужное свойство компонента} end; |
#2
|
|||
|
|||
Почти такое можно организовать только для Published свойств.
Смотреть в сторону PropInfo |
Этот пользователь сказал Спасибо icWasya за это полезное сообщение: | ||
morebeauty (14.03.2013)
|
#3
|
||||
|
||||
Если кому интересно, вот такой получился класс. Правда не все методы еще реализовал, но основа готова.
Код:
type TComp = record Component:TComponent; P:String; Enabled:Boolean; Link:Boolean; Variable:string; end; TComps = array of TComp; TLinking = class private FSL:TStringList; FComponents:TComps; function GetVal(name: string): string; procedure SetVal(name: string; const Value: string); function GetCCount: Integer; function GetProperty(AControl: TPersistent; AProperty: string): PPropInfo; public property Value[name:string]:string read GetVal write SetVal; default; property CCount:Integer read GetCCount; function AddComponent(const C:TComponent;P,V:String):Boolean; constructor Create; destructor Destroy; end; implementation function TLinking.AddComponent(const C: TComponent; P, V: String): Boolean; begin SetLength(FComponents,Length(FComponents)+1); FComponents[High(FComponents)].Component:=c; FComponents[High(FComponents)].P:=p; FComponents[High(FComponents)].Enabled:=True; FComponents[High(FComponents)].Link:=False; FComponents[High(FComponents)].Variable:=v; end; constructor TLinking.Create; begin inherited; FSL:=TStringList.Create; end; destructor TLinking.Destroy; begin FSL.Free; inherited; end; function TLinking.GetCCount: Integer; begin result:=Length(FComponents); end; function TLinking.GetProperty(AControl: TPersistent; AProperty: string): PPropInfo; var i: Integer; props: PPropList; typeData: PTypeData; begin Result := nil; if (AControl = nil) or (AControl.ClassInfo = nil) then Exit; typeData := GetTypeData(AControl.ClassInfo); if (typeData = nil) or (typeData^.PropCount = 0) then Exit; GetMem(props, typeData^.PropCount * SizeOf(Pointer)); try GetPropInfos(AControl.ClassInfo, props); for i := 0 to typeData^.PropCount - 1 do begin with Props^[i]^ do if (Name = AProperty) then result := Props^[i]; end; finally FreeMem(props); end; end; function TLinking.GetVal(name: string): string; begin Result:=FSL.Values[name]; end; procedure TLinking.SetVal(name: string; const Value: string); var i:Integer; PropInfo:PPropInfo; begin FSL.Values[name]:=Value; for i:=0 to CCount-1 do begin if LowerCase(FComponents[i].Variable)=LowerCase(name) then begin PropInfo := GetProperty(FComponents[i].Component, FComponents[i].P); if PropInfo <> nil then SetStrProp(FComponents[i].Component, PropInfo, Value); end; end; end; Ну и работает как то так: Код:
procedure TForm1.FormShow(Sender: TObject); begin Linking:=TLinking.Create; //Далее Edit1.Text и Label1.Caption связываются с некоторой переменной Var1 Linking.AddComponent(Edit1,'Text','Var1'); Linking.AddComponent(Label1,'Caption','Var1'); end; procedure TForm1.btn1Click(Sender: TObject); begin Linking['Var1']:='123'; //Меняется переменная Var1 - меняются привязанные к ней свойства компонентов end; На этом сайте так же нашел способы изменения свойств разного типа (не только string) http://www.delphisources.ru/pages/fa...ps_values.html Последний раз редактировалось morebeauty, 14.03.2013 в 12:27. |
#4
|
||||
|
||||
Хрень это все........
Код:
type TForm1 = class(TForm) btn1: TButton; txt1: TEdit; lbl1: TLabel; lbl2: TLabel; lbl3: TLabel; procedure btn1Click(Sender: TObject); procedure FormShow(Sender: TObject); procedure txt1Change(Sender: TObject); private FMyVar: string; function GetMyVar: string; procedure SetMyVar(const Value: string); { Private declarations } public property MyVar:string read GetMyVar write SetMyVar; { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btn1Click(Sender: TObject); begin MyVar:='123'; end; function TForm1.GetMyVar: string; begin result:=FMyVar; end; procedure TForm1.SetMyVar(const Value: string); begin FMyVar:=Value; if txt1.text<>Fmyvar then txt1.Text:=FMyVar; lbl1.Caption:=FMyVar; lbl2.Caption:=FMyVar; lbl3.Caption:=FMyVar; end; procedure TForm1.txt1Change(Sender: TObject); begin MyVar:=txt1.Text; end; |
#5
|
||||
|
||||
Цитата:
Ну ты понел ^_^. |