AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

MVVM in der Realität

Ein Thema von Union · begonnen am 8. Sep 2013 · letzter Beitrag vom 10. Jun 2015
 
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#11

AW: MVVM in der Realität

  Alt 12. Sep 2013, 14:23
Also ich habe einen Lösungsansatz, den ich in Ausschnitten beschreibe.

Die View ist ein normales TForm. Beim Erzeugen wird das Binding erstellt.
Delphi-Quellcode:
constructor TfrmMain.Create(AOwner: TComponent);
begin
  ViewModel := TViewModelKunde.create;
  inherited;

  // Binding einzeln erzeugen
  FBindingList := TBindingList.Create;
  FNameBindObject := TEditBinding.Create;
  FNameBindObject.Control := edtNameTest;
  FNameBindObject.ControlProp := 'Text';
  FNameBindObject.BindObject := ViewModel.Kunde;
  FNameBindObject.BindProp := 'Name';
  // Und hinzufügen
  FBindingList.Add(FNameBindObject);
  // Oder direkt
  FBindingList.Add(TEditBinding.Create(edtKdNrTest, ViewModel.Kunde, 'Text', 'Kdnr'));
  // Hier wird alles initialisiert
  FBindingList.Load;
end;
Im Viewmodel wird dann die UI-Relevante Logik implementiert, z.b. ob gespeichert werden darf.
unit Viewmodel.Kunde;

Delphi-Quellcode:
interface

uses Model.Kunde;

type
  TViewModelKunde = class
  strict private
    FKunde: TKunde;
    procedure SetKunde(const Value: TKunde);
    function GetCanSave: boolean;
  published
    constructor create;
    property Kunde : TKunde read FKunde write SetKunde;
    procedure Save;
    property CanSave : boolean read GetCanSave;
  end;

// Kann aus dem View heraus benutzt werden um festzustellen ob z.B. Speicherung zulässig
function TViewModelKunde.GetCanSave: boolean;
begin
  result := FKunde.IsValid;
end;
Und das Model stellet eben die Daten dar, in diesem Fall ganz schlicht.
Delphi-Quellcode:
unit Model.Kunde;

interface
uses
  System.Classes;

type
  MaxLen = class(TCustomAttribute)
  private
    FMaxLen : integer;
  public
    constructor Create(const ALength : integer); overload;
    // Per Konvention muss die Attribut-Property immer "Value" heißen
    property Value : integer read FMaxLen;
  end;

  TKunde = class
  strict private
    FName: string;
    FKdNr: integer;
    FStrasse: string;
    procedure SetKdNr(const Value: integer);
    procedure SetName(const Value: string);
    procedure SetStrasse(const Value: string);
    function GetIsValid: boolean;
  public
    property KdNr : integer read FKdNr write SetKdNr;
    [MaxLen(20)]
    property Name : string read FName write SetName;
    property Strasse : string read FStrasse write SetStrasse;
    property IsValid : boolean read GetIsValid;
  end;

implementation

{ TKunde }

function TKunde.GetIsValid: boolean;
begin
  result := (FKdNr > 0) and
            (FName <> '') and
            (FStrasse <> '');
end;

procedure TKunde.SetKdNr(const Value: integer);
begin
  FKdNr := Value;
end;

procedure TKunde.SetName(const Value: string);
begin
  FName := Value;
end;

procedure TKunde.SetStrasse(const Value: string);
begin
  FStrasse := Value;
end;

{ MaxLen }

constructor MaxLen.Create(const ALength: integer);
begin
  FMaxLen := ALength;
end;
Das ganze wird verbunden durch das Binding. Wenn ein Binding erzeugt wird mit z.b.
Delphi-Quellcode:
TEditBinding.Create(edtKdNrTest, ViewModel.Kunde, 'Text', 'Kdnr')
TEditBinding.Load
wird eigentlich nur folgendes festgelegt:

1. edtKdnrTest.Text entspricht ViewModel.Kunde.Kdnr
2. Evtl. im Model angelegte Attribute werden ausgelesen und in die UI eingetragen (Hier MaxLen)
3. Der OnExit Event wird durch einen eigenen Event überschrieben, der Original-Event wird intern gemerkt

Immer wenn jetzt der OnExit des Edit aufgerufen wird, wird zunächst der Inhalt an das Model übertragen und dann ein evtl. vorher vorhandener Original-Event aufgerufen.
Delphi-Quellcode:
procedure TCustomBinding.DoNotify(Sender: TObject);
begin
  Save;
  if Assigned(FOldNotify) then
    FOldNotify(Sender);
end;

procedure TCustomBinding.Save;
var
  AValue : Variant;
begin
  AValue := GetPropValue(FControl, FControlProp);
  SetPropValue(FBindObject, FBindProp, AValue);
end;
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz