Einzelnen Beitrag anzeigen

FAM

Registriert seit: 22. Dez 2014
47 Beiträge
 
Delphi XE Enterprise
 
#22

AW: MVC + Observer Pattern Konzept / Was haltet Ihr davon

  Alt 6. Feb 2015, 11:28
hmm irgendwie klappt das doch nicht so wie ich mir das dachte....

wenn ich aus der Main heraus das Model ändere (über die ModelView) dann wird TForm1.ViewModelStockpilePropertyChanged ausgeführt, wenn ich aber aus dem ModelView das Model ändere passiert nichts... eigentlich logisch und denn wieder auch nicht

jemand eine idee? ich vermute ich muss noch ein Event vom ModelView in Richtung View dispatchen?!


Main
Delphi-Quellcode:
...
  // Create reference of ViewModelStockpile (Scope to Model.Stockpile)
  FViewModelStockpile := TViewModelStockpile.Create;

  // Register PropertyChanged-Methode if changing the
  // Datamodel in ViewModelStockpile
  FViewModelStockpile.registerOn(ViewModelStockpilePropertyChanged);

...

procedure TForm1.ViewModelStockpilePropertyChanged;
begin
  EditContentbarStartMarker.Text := FViewModelStockpile.Foo;
  ShowMessage('Model wurde geändert');
end;
...

view.model.stockpile
Delphi-Quellcode:
unit view.model.stockpile;

interface

uses
  model, model.stockpile;

type

  { View Model for Stockpile }

  TViewModelStockpile = class(TModel)
  private
     FModel: TStockpileModel;
    data: TArray<Double>;
    cdsBioLife: String;

    FBar: String;
    FFoo: string;
    function GetBioLife: String;

    procedure SetBar(const Value: String);
    procedure SetFoo(const Value: string);

  public
    constructor Create;
    function GetData: TArray<Double>;
    procedure SetData(data: TArray<Double>);


    property BioLife: String read GetBioLife;
    destructor destroy; override;

    property Foo: string read FFoo write SetFoo;
    property Bar: String read FBar write SetBar;

  end;

implementation

{ TViewModelStockpile }

constructor TViewModelStockpile.Create;
begin
 inherited Create;
  FModel := TStockpileModel.Create;
  Foo := 'test';
end;

destructor TViewModelStockpile.destroy;
begin
   FModel.Free;
  inherited;
end;

procedure TViewModelStockpile.SetBar(const Value: String);
begin
  if FBar <> Value then
  begin
    FBar := Value;
    notify;
  end;
end;

procedure TViewModelStockpile.SetFoo(const Value: string);
begin
  if FFoo <> Value then
  begin
    FFoo := Value;

    ShowMessage('notify');
    notify;
    // OnPropertyChanged('Foo');
  end;
end;

function TViewModelStockpile.GetBioLife: String;
begin
  Result := cdsBioLife;
end;

function TViewModelStockpile.GetData: TArray<Double>;
begin
  Result := self.data;
end;

procedure TViewModelStockpile.SetData(data: TArray<Double>);
begin
  self.data := data;
  // alle Ereignis-Behandlungs-Routinen der Liste aufrufen
  // wurde mit registerOn an das Model regestriert
  notify;
end;

end.

Model(Base)


Delphi-Quellcode:
unit model;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, jpeg, StdCtrls, pngimage, JvPanel, JvExExtCtrls,
  JvExtComponent, Series, TeeShape, TeEngine, TeeProcs, Chart, Math, TeeGDIPlus,
  ComCtrls, JvExComCtrls, JvComCtrls, dOPCIntf, dOPCComn, dOPCDA, dOPC;

type
  TEvent = procedure of object;

  TModel = class
  protected
    // interne Liste
    OnChange: array of TEvent;
    // Aufruf aller Routinen der Liste
    procedure notify;
    destructor destroy; override;
  public
    // neuer 'Event-Handler' in Liste
    procedure registerOn(routine: TEvent);
    // 'Event-Handler' aus Liste entfernen
    procedure registerOff(routine: TEvent);
  end;

implementation

// registriert neue routinen an den controller
procedure TModel.registerOn(routine: TEvent);
var
  n: integer;
begin
  n := Length(OnChange);
  SetLength(OnChange, n + 1);
  OnChange[n] := routine;

end;

// de-registriert routinen vom controller
procedure TModel.registerOff(routine: TEvent);
var
  i, j: integer;
begin
  i := Low(OnChange);
  while i <= High(OnChange) do // High liefert -1 bei leerem Array
  begin
    if @OnChange[i] = @routine // mit '@' nur Adressen vergleichen
    then
    begin
      for j := i to High(OnChange) - 1 do
        OnChange[j] := OnChange[j + 1];
      SetLength(OnChange, Length(OnChange) - 1);
    end
    else
      i := i + 1;
  end;
end;

// alle Ereignis-Behandlungs-Routinen der Liste aufrufen
destructor TModel.destroy;
begin
//
  inherited;
end;

procedure TModel.notify;
var
  i: integer;
begin
  for i := Low(OnChange) to High(OnChange) do
    OnChange[i];
end;

end.

Geändert von FAM ( 6. Feb 2015 um 11:49 Uhr)
  Mit Zitat antworten Zitat