Author: Tomas Rutkauskas
I have a frame with two panels on it (right and left). The left panel is a pretty
standard treeview. The right panel is a representation of the data record for the
selected node in the tree view. The right panel is dynamic, that is it is
constructed on the fly at run time as the users have the ability to define what
fields they wish to show and what the labels are for those fields.
I need the right panel to change the treeview node text when the record in the
right panel is posted. The general consensus is that it'd best be done with a
callback, but I've never done one before. Can anyone give me a simple example of
how to do this?
Answer:
What you are describing is a Mediator Pattern. In essence, you set up a class which
is aware of your two (or more) components. Set up properties to record changes and
then in the appropriate event handler, simply assign the new values. The Mediator
is solely responsible for synchronizing the two.
Very simple example (yours will be slightly more complex, but surprisingly probably
won't have too much more code):
1 TEditBoxMediator = class2 private3 FIsChanging: boolean;
4 FFirstBox: TEdit;
5 FSecondBox: TEdit;
6 function GetText: string;
7 procedure SetText(Value: string);
8 public9 property Text: stringread GetText write SetText;
10 constructor Create(const FirstBox, SecondBox: TEdit);
11 end;
12 13 constructor TEditBoxMediator.Create(const FirstBox, SecondBox: TEdit);
14 begin15 inherited Create;
16 FFirstBox := FirstBox;
17 FSecondBox := SecondBox;
18 FIsChanging := False;
19 end;
20 21 function TEditBoxMediator.GetText: string;
22 begin23 Result := FFirstBox.Text;
24 end;
25 26 procedure TEditBoxMediator.SetText(Value: string);
27 begin28 if FIsChanging then29 Exit;
30 FIsChanging := True;
31 if FFirstBox.Text <> Value then32 FFirstBox.Text := Value;
33 if FSecondBox.Text <> Value then34 FSecondBox.Text := Value;
35 FIsChanging := False;
36 end;
37 38 procedure TForm1.Create {...}39 begin40 FEditBoxMediator := TEditBoxMediator.Create(Edit1, Edit2);
41 end;
42 43 procedure TForm1.Edit1Change(Sender: TObject);
44 begin45 FEditBoxMediator.Text := Edit1.Text;
46 end;
and so on.
The idea is that the mediator handles the changes (and uses the internal flag to
prevent an endless
loop).