How to synchronize two controls (Views: 33)
Problem/Question/Abstract: 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 synchonizing the two. Very simple example (yours will be slightly more complex, but surprisingly probably won't have too much more code): TEditBoxMediator = class private FIsChanging: boolean; FFirstBox: TEdit; FSecondBox: TEdit; function GetText: string; procedure SetText(Value: string); public property Text: string read GetText write SetText; constructor Create(const FirstBox, SecondBox: TEdit); end; constructor TEditBoxMediator.Create(const FirstBox, SecondBox: TEdit); begin inherited Create; FFirstBox := FirstBox; FSecondBox := SecondBox; FIsChanging := False; end; function TEditBoxMediator.GetText: string; begin Result := FFirstBox.Text; end; procedure TEditBoxMediator.SetText(Value: string); begin if FIsChanging then Exit; FIsChanging := True; if FFirstBox.Text <> Value then FFirstBox.Text := Value; if FSecondBox.Text <> Value then FSecondBox.Text := Value; FIsChanging := False; end; procedure TForm1.Create {...} begin FEditBoxMediator := TEditBoxMediator.Create(Edit1, Edit2); end; procedure TForm1.Edit1Change(Sender: TObject); begin FEditBoxMediator.Text := Edit1.Text; end; and so on. The idea is that the mediator handles the changes (and uses the internal flag to prevent an endless loop). |