|
Registriert seit: 5. Jan 2005 Ort: Stadthagen 9.454 Beiträge Delphi 10 Seattle Enterprise |
#5
Richtig spannend wird es, wenn man das erweitern möchte:
z.B. benötigen wir auch eine Aktivitätsanzeige mit einem Fortschritt. Nichts leichter als das
Delphi-Quellcode:
Schon haben wir eine Aktivität mit Fortschritt.
unit ViewModel.ActivityViewModel;
interface uses MVVM.ViewModel.ViewModelBase; type TActivityViewModel = class( TViewModelBase ) private FInfo: string; procedure SetInfo( const Value: string ); public property Info: string read FInfo write SetInfo; end; TProgressActivityViewModel = class( TActivityViewModel ) private FProgress: Single; procedure SetProgress( const Value: Single ); public property Progress: Single read FProgress write SetProgress; end; implementation { TActivityViewModel } procedure TActivityViewModel.SetInfo( const Value: string ); begin if FInfo <> Value then begin FInfo := Value; OnPropertyChanged( 'Info' ); end; end; { TProgressActivityViewModel } procedure TProgressActivityViewModel.SetProgress( const Value: Single ); begin if FProgress <> Value then begin FProgress := Value; OnPropertyChanged( 'Progress' ); end; end; end. Dann mal in das MainViewModel und die Aktivitäten eingebaut (nur die Änderungen)
Delphi-Quellcode:
Da wir TProgressActivityViewModel
von TActivityViewModel
abgleitet haben brauchen wir die View nicht ändern um lauffähig zu bleiben. Nur der Progress wird eben nicht angezeigt, aber die Funktionalität bleibt gewahrt.
unit ViewModel.MainViewModel;
interface uses System.SysUtils, System.Classes, System.Threading, de.itnets.Commands, de.itnets.References, MVVM.ViewModel.ViewModelBase, ViewModel.WorkspaceViewModel, ViewModel.ActivityViewModel; type TMainViewModel = class( TWorkspaceViewModel ) private FSomeProgressActionCommand: ICommand; FSomeRandomActionCommand: ICommand; function GetSomeProgressActionCommand: ICommand; function GetSomeRandomActionCommand: ICommand; public property SomeProgressActionCommand: ICommand read GetSomeProgressActionCommand; property SomeRandomActionCommand: ICommand read GetSomeRandomActionCommand; end; implementation { TMainViewModel } function TMainViewModel.GetSomeProgressActionCommand: ICommand; begin if not Assigned( FSomeProgressActionCommand ) then FSomeProgressActionCommand := TRelayCommand.Create( procedure var LActivity: AutoRef<TProgressActivityViewModel>; begin SetCanClose( False ); // Aktivitätsanzeige setzen LActivity := TProgressActivityViewModel.Create; LActivity.Reference.Info := 'Performing SomeProgressAction'; SetActivity( LActivity ); // Task starten TTask.Run( procedure var LIdx: Integer; begin LActivity.Reference.Progress := 0; for LIdx := 1 to 10 do begin Sleep( 200 ); LActivity.Reference.Progress := LIdx * 10; end; // Aktivitätsanzeige ausschalten TThread.Synchronize( nil, procedure begin SetActivity( nil ); SetCanClose( True ); end ); end ); end, function: Boolean begin Result := not FActivity.IsAssigned; end ); Result := FSomeProgressActionCommand; end; function TMainViewModel.GetSomeRandomActionCommand: ICommand; begin if not Assigned( FSomeRandomActionCommand ) then FSomeRandomActionCommand := TRelayCommand.Create( procedure var LActivity: AutoRef<TActivityViewModel>; LProgressActivity: AutoRef<TProgressActivityViewModel>; begin SetCanClose( False ); // Aktivitätsanzeige setzen LActivity := TActivityViewModel.Create; LProgressActivity := TProgressActivityViewModel.Create; SetActivity( LActivity ); // Task starten TTask.Run( procedure var LIdx: Integer; begin TThread.Queue( nil, procedure begin LActivity.Reference.Info := 'Init data...'; SetActivity( LActivity ); end ); Sleep( 1000 ); TThread.Queue( nil, procedure begin LProgressActivity.Reference.Info := 'Reading data...'; LProgressActivity.Reference.Progress := 0; SetActivity( LProgressActivity ); end ); for LIdx := 1 to 20 do begin Sleep( 150 ); TThread.Queue( nil, procedure begin LProgressActivity.Reference.Progress := LIdx * 5; end ); end; TThread.Queue( nil, procedure begin LActivity.Reference.Info := 'Cleanup system...'; SetActivity( LActivity ); end ); Sleep( 1000 ); // Aktivitätsanzeige ausschalten TThread.Synchronize( nil, procedure begin SetActivity( nil ); SetCanClose( True ); end ); end ); end, function: Boolean begin Result := not FActivity.IsAssigned; end ); Result := FSomeRandomActionCommand; end; end. Ok, dann bauen wir uns eine entsprechende View (Frame mit einer ProgressBar und einem TextFeld) und bringen das auf die MainView. Damit das dann auch genutzt wird benötigen wir diese Änderungen an der View (nur die geänderten Teile)
Delphi-Quellcode:
Im Anhang nur die Exe
unit View.Form.MainView;
interface uses de.itnets.Events, de.itnets.References, MVVM.ViewModel.ViewModelBase, ViewModel.MainViewModel, System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, View.Form.WorkspaceView, MVVM.View.FMX.Frame.Base, FMX.Objects, System.Actions, FMX.ActnList, FMX.Layouts, View.Frame.AcitivityView, View.Frame.ProgressAcitivityView; type TMainView = class( TWorkspaceView ) ActivityCurtain: TRectangle; ActivityView1: TActivityView; ToolBar1: TToolBar; SpeedButton1: TSpeedButton; ActionList1: TActionList; SomeActionAction: TAction; CloseAction: TAction; SpeedButton2: TSpeedButton; SomeProgressActionAction: TAction; SpeedButton3: TSpeedButton; ProgressActivityView1: TProgressActivityView; SomeRandomActionAction: TAction; SpeedButton4: TSpeedButton; procedure SomeActionActionExecute( Sender: TObject ); procedure SomeActionActionUpdate( Sender: TObject ); procedure CloseActionExecute( Sender: TObject ); procedure CloseActionUpdate( Sender: TObject ); procedure SomeProgressActionActionExecute( Sender: TObject ); procedure SomeProgressActionActionUpdate( Sender: TObject ); procedure SomeRandomActionActionExecute( Sender: TObject ); procedure SomeRandomActionActionUpdate( Sender: TObject ); private FMain: WeakRef<TMainViewModel>; protected procedure AttachToViewModel( AViewModel: TViewModelBase ); override; procedure DetachFromViewModel( AViewModel: TViewModelBase ); override; procedure ViewModelPropertyChanged( Sender: TObject; const e: TPropertyChangedArgs ); override; public end; var MainView: TMainView; implementation {$R *.fmx} uses System.StrUtils, ViewModel.ActivityViewModel; { TMainView } procedure TMainView.SomeProgressActionActionExecute( Sender: TObject ); begin inherited; FMain.Reference.SomeProgressActionCommand.Execute; end; procedure TMainView.SomeProgressActionActionUpdate( Sender: TObject ); begin inherited; TAction( Sender ).Enabled := FMain.IsAssigned and FMain.Reference.SomeProgressActionCommand.CanExecute; end; procedure TMainView.SomeRandomActionActionExecute( Sender: TObject ); begin inherited; FMain.Reference.SomeRandomActionCommand.Execute; end; procedure TMainView.SomeRandomActionActionUpdate( Sender: TObject ); begin inherited; TAction( Sender ).Enabled := FMain.IsAssigned and FMain.Reference.SomeRandomActionCommand.CanExecute; end; procedure TMainView.ViewModelPropertyChanged( Sender: TObject; const e: TPropertyChangedArgs ); begin inherited; if FMain.IsAssigned then begin if e.Matches( ['Active', 'DisplayName'] ) then begin Caption := FMain.Reference.DisplayName + ' (' + IfThen( FMain.Reference.Active, 'Active', 'Inactive' ) + ')'; end; if e.Match( 'Activity' ) then begin ActivityCurtain.BringToFront; ActivityCurtain.Visible := Assigned( FMain.Reference.Activity ); if FMain.Reference.Activity is TProgressActivityViewModel then begin ActivityView1.Visible := False; ActivityView1.SetViewModel( nil ); ProgressActivityView1.Visible := True; ProgressActivityView1.BringToFront; ProgressActivityView1.SetViewModel( FMain.Reference.Activity ); end else if FMain.Reference.Activity is TActivityViewModel then begin ProgressActivityView1.Visible := False; ProgressActivityView1.SetViewModel( nil ); ActivityView1.Visible := Assigned( FMain.Reference.Activity ); ActivityView1.BringToFront; ActivityView1.SetViewModel( FMain.Reference.Activity ); end else begin ActivityView1.Visible := False; ActivityView1.SetViewModel( nil ); ProgressActivityView1.Visible := False; ProgressActivityView1.SetViewModel( nil ); end; end; end end; end.
Kaum macht man's richtig - schon funktioniert's
![]() Zertifikat: Sir Rufo (Fingerprint: ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60) |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |