unit ProductDetailScherm; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections, Vcl.ExtCtrls, Vcl.ComCtrls, Vcl.CheckLst, Subscherm, Navigator, ApplicationContext, ProductsAgent, ObserverPattern, CheckCombo; resourceString GEEN_DATA_CAPTION = 'Geen product geselecteerd'; type TFormProductDetail = class(TFormSubscherm) LabelOmschrijving1: TLabel; LabelOmschrijving2: TLabel; Label1: TLabel; LabelProductNaam: TLabel; ListViewVerpakkingen: TListView; GroupBox1: TGroupBox; ButtonNieuw: TButton; ButtonVerwijder: TButton; LabelProductNummer: TLabel; Label17: TLabel; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ListViewVerpakkingenSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); private FProductsContextSubject: TSubject; FProductsContextSubjectObserver: TSubjectObserver; FVerpakkingenContextSubject: TSubject; FVerpakkingenContextSubjectObserver: TSubjectObserver; FProductsAgent: TProductsAgent; LabelGeenData: TLabel; procedure UpdateGuiProduct(Sender: TObject); procedure UpdateGuiVerpakkingen(Sender: TObject); procedure LaadProductVerpakkingen(GeselecteerdProduct: TProductInformatie); procedure UpdateVerpakkingControlsEnableStatus(); procedure UpdateGuiProductAanwezigheid(Aanwezig: Boolean); public Constructor Create(AOwner: TComponent; Navigator: INavigator; ApplicationContext: TApplicationContext; ProductsContextSubject: TSubject; VerpakkingContextSubject: TSubject; ProductsAgent: TProductsAgent); end; implementation uses OptiServerService, Util, System.StrUtils, CustomPanelVerpakkingParameter; {$R *.dfm} Constructor TFormProductDetail.Create(AOwner: TComponent; Navigator: INavigator; ApplicationContext: TApplicationContext; ProductsContextSubject: TSubject; VerpakkingContextSubject: TSubject; ProductsAgent: TProductsAgent); begin inherited Create(AOwner, Navigator, ApplicationContext); self.FProductsContextSubject := ProductsContextSubject; self.FProductsContextSubjectObserver := TSubjectObserver.Create(self); self.FProductsContextSubjectObserver.OnChange := UpdateGuiProduct; self.FVerpakkingenContextSubject := VerpakkingContextSubject; self.FVerpakkingenContextSubjectObserver := TSubjectObserver.Create(self); self.FVerpakkingenContextSubjectObserver.OnChange := UpdateGuiVerpakkingen; self.FProductsAgent := ProductsAgent; end; procedure TFormProductDetail.FormCreate(Sender: TObject); begin // Registreer bij observer FProductsContextSubject.RegisterObserver(FProductsContextSubjectObserver); FVerpakkingenContextSubject.RegisterObserver(FVerpakkingenContextSubjectObserver); end; procedure TFormProductDetail.FormDestroy(Sender: TObject); begin FProductsContextSubject.UnregisterObserver(FProductsContextSubjectObserver); FVerpakkingenContextSubject.UnregisterObserver(FVerpakkingenContextSubjectObserver); end; procedure TFormProductDetail.UpdateGuiProduct(Sender: TObject); var GeselecteerdProduct: TProductInformatie; begin GeselecteerdProduct := ApplicationContext.ProductsContext.GeselecteerdProduct; if GeselecteerdProduct = nil then begin UpdateGuiProductAanwezigheid(False); exit; end; // Product is geselecteerd // Update met data uit geselecteerd product LabelOmschrijving1.Caption := GeselecteerdProduct.Omschrijving1; LabelOmschrijving2.Caption := GeselecteerdProduct.Omschrijving2; LabelProductNaam.Caption := GeselecteerdProduct.Kol1; LabelProductNummer.Caption := intToStr(GeselecteerdProduct.ProductNr); UpdateGuiProductAanwezigheid(True); // Verpakkingen opzoeken horende bij dit geselecteerde product LaadProductVerpakkingen(GeselecteerdProduct); end; procedure TFormProductDetail.LaadProductVerpakkingen(GeselecteerdProduct: TProductInformatie); var ErrorMessage: string; begin // Product informatie ophalen FProductsAgent.ZoekProductVerpakkingenMetProductNr(GeselecteerdProduct.ProductNr, self.ApplicationContext.UserContext, self.ApplicationContext.ProductVerpakkingContext); if self.ApplicationContext.ProductVerpakkingContext.IsOK then // Gelukt else begin // Opzoeking gefaald ErrorMessage := self.ApplicationContext.ProductVerpakkingContext.ErrorMessage; if self.ApplicationContext.ProductVerpakkingContext.InternalErrorMessage <> '' then ErrorMessage := ErrorMessage + sLineBreak + self.ApplicationContext.ProductVerpakkingContext.InternalErrorMessage; MessageDlg(ErrorMessage, TMsgDlgType.mtInformation, [mbOK], 0, mbCancel); end; end; procedure TFormProductDetail.ListViewVerpakkingenSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); begin if Selected then begin if ApplicationContext.ProductVerpakkingContext.GeselecteerdeVerpakking <> TProductVerpakking(ListViewVerpakkingen.Selected.Data) then begin // Product selecteren. Wij doen de selectie en willen dus niet opnieuw worden opgeroepen. FVerpakkingenContextSubjectObserver.Enabled := False; ApplicationContext.ProductVerpakkingContext.GeselecteerdeVerpakking := TProductVerpakking(ListViewVerpakkingen.Selected.Data); FVerpakkingenContextSubjectObserver.Enabled := True; end; Navigator.NavigeerNaar(NAVTOONPRODUCTVERPAKKING); end; end; procedure TFormProductDetail.UpdateGuiVerpakkingen(Sender: TObject); var ProductVerpakking: TProductVerpakking; begin // List view (grid). We vullen de lijst iedere keer opnieuw om wijzigingen aan verpakkingen te reflecteren. ListViewVerpakkingen.Items.BeginUpdate; ListViewVerpakkingen.Clear(); for ProductVerpakking in TProductVerpakkingenContext(Sender).ProductVerpakkingen do begin With ListViewVerpakkingen.Items.Add Do begin Data := ProductVerpakking; // Caption := IntToStr(Product.ProductNr); // Deze casting geeft geen access violation Caption := intToStr(ProductVerpakking.CutOrder); SubItems.Add(ProductVerpakking.MetaCaptionDisplay); SubItems.Add(ProductVerpakking.Breedte + ' x ' + ProductVerpakking.Diepte + ' x ' + ProductVerpakking.Hoogte); SubItems.Add(ProductVerpakking.Aantal); SubItems.Add(ProductVerpakking.MaxCombinAantal); SubItems.Add(ProductVerpakking.DeelVanCaption); SubItems.Add(ProductVerpakking.ID); end; end; ListViewVerpakkingen.Items.EndUpdate; // Bepaal het geselecteerde item in de list view if TProductVerpakkingenContext(Sender).GeselecteerdeVerpakking = nil then begin // Nog geen verpakking gekozen, selecteer er zelf een. Default de eerste. if TProductVerpakkingenContext(Sender).ProductVerpakkingen.Count > 0 then // Default eerste verpakking selecteren ListViewVerpakkingen.ItemIndex := 0; end else begin // Er was reeds een verpakking gekozen, selecteer de juiste index van de ListView ListViewVerpakkingen.ItemIndex := TProductVerpakkingenContext(Sender) .ProductVerpakkingen.IndexOf(TProductVerpakkingenContext(Sender).GeselecteerdeVerpakking); end; UpdateVerpakkingControlsEnableStatus; end; procedure TFormProductDetail.UpdateVerpakkingControlsEnableStatus(); var VerpakkingAanwezigEnGeselecteerd: Boolean; begin // Details controls enable status aanpassen naargelang er een verpakking geselecteerd is. VerpakkingAanwezigEnGeselecteerd := (ListViewVerpakkingen.Items.Count > 0) and (ListViewVerpakkingen.ItemIndex >= 0); ButtonVerwijder.Enabled := VerpakkingAanwezigEnGeselecteerd; end; procedure TFormProductDetail.UpdateGuiProductAanwezigheid(Aanwezig: Boolean); var I: Integer; begin if Aanwezig then begin // Skip update als alles al zichtbaar staat. if Assigned(LabelGeenData) = False then exit; // Wel resultaten, toon alles. for I := 0 to self.ControlCount - 1 do if Assigned(self.Controls[I]) then self.Controls[I].Visible := True; LabelGeenData.Visible := False; FreeAndNil(LabelGeenData); end else begin // Skip update als melding al getoond wordt en alles onzichtbaar staat. if Assigned(LabelGeenData) then exit; // Geen resultaten, verberg kinderen, toon melding (label) en stop. for I := 0 to self.ControlCount - 1 do if Assigned(self.Controls[I]) then self.Controls[I].Visible := False; // Label tonen LabelGeenData := TLabel.Create(self); with LabelGeenData do begin Parent := self; Caption := GEEN_DATA_CAPTION; Font.Size := 15; // Centreren: https://stackoverflow.com/questions/18545937/make-a-component-appear-in-the-middle-of-form-no-matter-what-screen-resolution Left := (self.Width - Width) div 2; Top := (self.Height - Height) div 2; Anchors := []; // Relatief tegenover parent end; end end; end.