(TObjectList)的对象可以知道(TMyObject)的某些值何时被更改?
一些例子:
TMyObject = class
oName: string;
end;
TMyObjectList = class(TObjectList<TMyObject>)
end;
procedure Form1.Button1.Click(Sender: TObject);
var
Obj: TMyObject;
List: TMyObjectList;
Begin
List:= TMyObjectList.Create;
Obj:= TMyObject.Create;
List.Add(Obj);
List[0].oName:= 'Test'; // here a want to know from var (List) when this object (Obj or List[0]) changed his value..
end;
感谢您的帮助。
答案 0 :(得分:7)
我刚刚将TObservableList<T>
类型添加到Spring4D(feature / observablelist分支)。它主要以.NET为模型,并使用INotifyPropertyChanged接口将其事件处理程序附加到支持它的任何对象。这个类已经成为DSharp的一部分很长一段时间了,并且在生产中使用。它可能会在未来发生一些变化,并成为图书馆的一部分。
以下是一个如何使用它的小例子,以便您了解:
program Project60;
{$APPTYPE CONSOLE}
uses
Spring,
Spring.Collections,
SysUtils;
type
TNotifyPropertyChangedBase = class(TInterfaceBase, INotifyPropertyChanged)
private
fOnPropertyChanged: Event<TPropertyChangedEvent>;
function GetOnPropertyChanged: IPropertyChangedEvent;
protected
procedure PropertyChanged(const propertyName: string);
end;
TMyObject = class(TNotifyPropertyChangedBase)
private
fName: string;
procedure SetName(const Value: string);
public
property Name: string read fName write SetName;
end;
TMain = class
procedure ListChanged(Sender: TObject; const item: TMyObject;
action: TCollectionChangedAction);
end;
{ TNotifyPropertyChangedBase }
function TNotifyPropertyChangedBase.GetOnPropertyChanged: IPropertyChangedEvent;
begin
Result := fOnPropertyChanged;
end;
procedure TNotifyPropertyChangedBase.PropertyChanged(
const propertyName: string);
begin
fOnPropertyChanged.Invoke(Self,
TPropertyChangedEventArgs.Create(propertyName) as IPropertyChangedEventArgs);
end;
{ TMyObject }
procedure TMyObject.SetName(const Value: string);
begin
fName := Value;
PropertyChanged('Name');
end;
{ TMain }
procedure TMain.ListChanged(Sender: TObject; const item: TMyObject;
action: TCollectionChangedAction);
begin
case action of
caAdded: Writeln('item added ', item.Name);
caRemoved, caExtracted: Writeln('item removed ', item.Name);
caChanged: Writeln('item changed ', item.Name);
end;
end;
var
main: TMain;
list: IList<TMyObject>;
o: TMyObject;
begin
list := TCollections.CreateObservableList<TMyObject>;
list.OnChanged.Add(main.ListChanged);
o := TMyObject.Create;
o.Name := 'o1';
list.Add(o);
o := TMyObject.Create;
o.Name := 'o2';
list.Add(o);
list[1].Name := 'o3';
Readln;
end.
答案 1 :(得分:2)
没有任何东西可以做你所要求的。您需要自己实施通知机制。这是Observer Pattern的经典场景。
这种模式的许多实现已经存在。一个显而易见的选择是在Spring4D中使用该实现。尼克霍奇斯最近出版的书More Coding in Delphi,包括了我将推荐的关于这种模式的章节。
答案 2 :(得分:-1)
找到方法,如何从TMyObject调用TObjectList的方法。在基础对象中使用TNotifyEvent。
示例:
TMyClass = class(TObject)
private
FName: string;
FOnNameEvent: TNotifyEvent;
procedure SetName(value: string);
public
property Name: string read FName write SetName;
property OnNameEvent: TNotifyEvent read FOnNameEvent write FOnNameEvent;
end;
procedure TMyClass.SetName(value: string);
begin
FName := value;
if Assigned(FOnNameEvent) then
FOnNameEvent(Self);
end;
procedure MyNameEvent(Sender: TObject);
var
i: Integer;
begin
for i := 0 to MyListOfMyClassObjects.Count -1 do
if Sender = MyListOfMyClassObjects.Item[i] then
begin
MessageBox(0, PChar(TMyClass(MyListOfMyClassObjects.Item[i]).Name), nil, MB_OK);
break;
end;
end;
procedure MyProc;
var
MyObject: TMyClass;
begin
MyObject := TMyClass.Create;
MyObject.OnNameEvent := MyNameEvent;
MyListOfMyClassObjects.Add(MyObject);
end;