Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   super-buggy MultiView-Komponente - Tipps? Workarounds? (https://www.delphipraxis.net/198024-super-buggy-multiview-komponente-tipps-workarounds.html)

knaeuel 27. Sep 2018 13:54

super-buggy MultiView-Komponente - Tipps? Workarounds?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

die MultiView-Komponente von Delphi 10.2 Tokyo nervt mich gewaltig. Ich würde sie aber gerne benutzen, weil es an sich ein schönes Feature ist.

[nicht-so-wichtig]
Damit, dass die Breite nicht sauber aus der IDE übernommen wird und auch mit den dauernd auftretenden Problemen innerhalb der IDE beim Anzeigen/Ausblenden des MultiView kann ich ja noch leben. Breite setze ich halt in OnCreate vom Formular, die Sichtbarkeit notfalls mit einem Klick in die Visible Checkbox. Dann gibts noch diverse Probleme mit Stati von Komponenten, die auf dem Multiview liegen, siehe hier zum Beispiel https://community.embarcadero.com/fo...view-component
Also lassen wir solche Komponenten im Multiview schonmal weg.
[/nicht-so-wichtig]

Aber jetzt gerade habe ich ein neues Problem, nämlich dass das erste Aufklappen nicht animiert wird. War bisher nie so, bisher kannte ich nur das Problem, dass der Multiview-Bereich beim ersten Aufklappen von der linken Seite hereingerutscht ist, wenn/obwohl die Komponente auf der rechten Seite liegt.

Gibt es für das Animationsproblem beim ersten Einblenden einen Workaround? Vielleicht irgendwelche Einstellungen, die man meiden sollte?

hier die aktuellen Einstellungen als Bildchen
Anhang 50031

Daniel 27. Sep 2018 14:04

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
Für welche Zielplattform entwickelst Du denn?
Ich habe erst kürzlich den MultiView für ein Android-Projekt eingesetzt und da verhält er sich absolut korrekt, Animation eingeschlossen.

knaeuel 27. Sep 2018 14:23

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
ich hatte das Verhalten auf Windows, Android und iOS - aber es hat mich stutzig gemacht, dass es bei dir funktionierte und zusätzlich kannte ich dieses Problem ja bis heute auch noch nicht.

Ich habe die Korrektur der Breite diesmal in die OnStartShowing-Procedure gesetzt. Das war wohl nicht so geschickt und löst das Problem aus. Ab dem zweiten Aufruf wird die Größe nur noch mit dem identischen Wert überschrieben => Animation läuft.

Bleibt nur noch das Problem, dass die MultiView beim ersten Öffnen von links hereinrutscht, auch wenn sie eigentlich auf der rechten Seite liegt. Jedes weitere Öffnen wird korrekt animiert.

Auch das Problem tritt nicht immer auf. Das Projekt, mit dem ich das Problem habe, will gerade nicht laufen. Ich melde mich gleich nochmal.

Rollo62 27. Sep 2018 18:27

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
MultiView und andere komplexere Komponenten funktionieren in simplen Anwendngen,
aber sobald es and Eingemachte geht poppen die Probleme hoch.

Ich für meinen Teil habe mich auf simplere Typen zurückgezogen, als TLayout, TRectangle, etc. und simuliere mir damit das Verhalten was ich brauche :stupid:

Rollo

knaeuel 28. Sep 2018 09:35

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
jetzt tritt das nächste problem auf.

windows: alles gut
iOS: alles gut
Android: beim Klick auf den Master-Button wird das aktuelle Formular leicht abgedunkelt - soweit noch alles ok - aber die MultiView wird nicht sichtbar. Sie liegt zwar über dem Formular und geht auch nur wieder zu (was sich optisch nur durch das Wiederaufhellen des Formulars bemerkbar macht), wenn ich in den Bereich klicke, den die MultiView nicht mehr überdecken würde, wenn man sie sehen könnte.

Also ich gebs jetzt wohl auch auf.

Dann werd ich mal versuchen, das Verhalten mit einem Rectangle, das ich zur Laufzeit erstelle und mit einem Frame füttere, den ich im Designer basteln kann, nachzubauen. Der Ansatz klingt für mich zumindest erstmal sinnvoll und recht übersichtlich. Oder gibts bessere Ideen?

Rollo62 28. Sep 2018 10:09

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
Testest du mir den Emba-Beispielen ?
Die funktionieren in der Regel, habs aber lange nicht mehr gecheckt.

Was ganz nett für die animierten Panels etc. ist wäre TFrameStand, hast du dir das mal angesehen ?

Ist vielleicht nicht ganz das was du suchst, aber zeigt schön was mit TFrames machbar ist und wie man da schönen Animationen reinbekommt.

Rollo

knaeuel 28. Sep 2018 12:52

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
die emba beispiele funktionieren. es ist so, wie du gesagt hast. kleine programme mit MultiView funktionieren noch...

Danke für den TFrameStand-Tipp! Sehr schöne Komponente! Damit kann man sehr einfach alles überall in jeder Größe einblenden/reinrutschen/was auch immer lassen :)

knaeuel 1. Okt 2018 13:32

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich habe mal mit TFrameStand von Andrea Magni, auf das Rollo netterweise hingewiesen hatte, das "Drawer"-Verhalten vom MultiView nachgebaut. Viel Spaß damit, wenn es jemand weiterbenutzen will.

TFramStand-Komponente von Andrea Magni bei GitHub

PS: nicht wundern, zu Demozwecken wird die von rechts hereinrutschende Ansicht auf den Kopf gestellt in "MyBeforeShowAsStand". Außerdem gibt es im Stylebook einen eher überflüssigen Button, der eine Action ausführt, die in OnCreate erstellt wird.

Fragen versuche ich auch gerne zu beantworten.

(das zip heißt MultiViewErsatz - es simuliert aber nur das Drawer-Verhalten des MultiView)

knaeuel 10. Okt 2018 11:22

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich hab das kleine Beispielprogramm nochmal überarbeitet. es passt sich nun automatisch an die bildschirmbreite an. getestet auf windows, android und ios

es war etwas unangenehm, das hinzubekommen. ich musste tatsächlich die animationen in den frame verlegen, weil ich ansonsten unter android und ios keinen zufgriff auf die eigenschaften der im Stylebook liegenden Animationen erlangt habe.
Unter Windows hats ohne Probleme funktioniert (FindSytelRe, auf iOS und Android gabs erstmal nur auf Umwegen überhaupt zugriff und der wurde dann auch noch ignoriert. Für mein Gefühl ist das ein Bug im Stylebook. Ich habe versucht, zu ergründen, woran es scheitert, aber der debugger/die ide ist dabei mehrfach abgestürzt, dann hatte ich irgendwann keine Lust mehr...

unter Windows, nicht aber unter iOS und Android funktionierte dieser Zugriff auf die Objekte im Stylebook:
Delphi-Quellcode:
var flani:TFloatAnimation;

  flani:=StyleBook1.Style.FindStyleResource('OnShowSlideInLeft', False) as TFloatAnimation;
  if Assigned(flani) then
    flani.StartValue:=-(LayoutForMVFrameLeft.Width+5);

  flani:=StyleBook1.Style.FindStyleResource('OnHideSlideOutLeft', False) as TFloatAnimation;
  if Assigned(flani) then
    flani.StopValue:=-(LayoutForMVFrameLeft.Width+5);
FindStyleResource lieferte unter iOS und Android nur für ganz wenige komponenten aus dem Stylebook einen Wert zurück, meistens aber nil. Die Elemente, die zu finden waren, lagen hierarchisch betrachtet eher oben, aber eine logik habe ich nicht entdeckt.

Das hier war der Ersatz für Android und iOS:

Delphi-Quellcode:
var flani:TFloatAnimation;
    rctngl:TRectangle;
    layout:TLayout;
    i,j:integer;


  //Workaround iOS/Android FindStyleResource: es werden nur weit oben stehende Komponenten sicher gefunden
  layout:=StyleBook1.Style.FindStyleResource('LikeMultiViewLeft', false) as TLayout;
  if Assigned(layout) then
  begin
    for i:=0 to layout.ChildrenCount-1 do
    begin
      if (layout.Children[i] is TRectangle) then
      begin
        if (layout.Children[i] as TRectangle).StyleName='RectangleContentBackgroundLeft' then
        begin
          rctngl:=(layout.Children[i] as TRectangle);
          for j:=0 to rctngl.ChildrenCount-1 do
          begin
            if (rctngl.Children[j] is TFloatAnimation) then
            begin
              if (rctngl.Children[j] as TFloatAnimation).StyleName='OnShowSlideInLeft' then
              begin
                (rctngl.Children[j] as TFloatAnimation).StartValue:=-(LayoutForMVFrameLeft.Width+5);
              end;
              if (rctngl.Children[j] as TFloatAnimation).StyleName='OnHideSlideOutLeft' then
                (rctngl.Children[j] as TFloatAnimation).StopValue:=-(LayoutForMVFrameLeft.Width+5);
            end;
          end;
        end;
      end;
    end;
  end;
aber leider brachte auch das keinen Erfolg. Zwar wurden die Werte tatsächlich überschrieben, aber die Animationen liefen weiterhin so ab, als wären noch die Originalwerte gesetzt. Das war schon verrückt...

wie gesagt, ob es an der TFramstand-Komponente oder an Delphi liegt, habe ich nicht erforscht.

Und weil das so verrückt war, fand ich es sinnig, die funktionierende Version hier nochmal zu posten :)

Rollo62 11. Okt 2018 05:17

AW: super-buggy MultiView-Komponente - Tipps? Workarounds?
 
FindStyleResource am Besten innerhalb von OnApplyStyleLookup oder OnUpdateObjcts benutzen,
in deinem Fall wird es aber schwierig, weil anscheinend gar keine Styled Controls benutzt werden.
Du könntest versuchen statt TLayout TPanel als Basiscontrol zu benutzen, das hat nämlich diese Events.

Ich würde auch versuchen nur ein Panel, statt Left/Right, zu verwenden.
Das sollte im aktuellen Design noch gut möglich sein, wenn man z.B. eine Eigenschaft definiert "FromLeft" die alle relevanten Komponenten, und die Richtung umkehrt
(also z.B. Align von MostRight zu MostLeft.
Es würde ressourcen sparen, und man müsste man sich nur noch um ein Panel kümmern.

Was ich gerne benutze ist dem Frame noch ein Interface zu geben, um es besser zu kapseln und zu modularisieren
Delphi-Quellcode:
type
  IMultiViewUserFrame = interface
  ['{FFE7532C-C203-412C-B658-10F720AADB05}']
      function GetFromLeft : Boolean;
      procedure SetFromLeft(const AValue : Boolean);

      property FromLeft : Boolean read GetFromLeft write SetFromLeft;
  end;


type
  TMultiViewUserFrame = class(TFrame, IMultiViewUserFrame)
  ...
Damit kann man dann beim Aufruf ein Interface benutzen, und dann dein gewünschtes Verhalten steuern.
Das macht aber beim aktuellen TFrameStand nicht so viel Sinn, weil ja auch immer die Klassen verfügbar sind, aber ich wollte immer mal versuchen den FrameStand etwas umzubauen, so das interfaces statt Klassen benutzt werden können.
Das würde den ganzen Aufbau etwas besser entkoppeln, und modularer und besser testbar machen.
Denn ich habe immer die Befürchtung das in größeren Projekten dieser Framestand mal schnell zu komplex werden kann (auf mobilen Plattformen).

Delphi-Quellcode:
procedure TForm1.ButtonShowLeftSideClick(Sender: TObject);
var flani:TFloatAnimation;
  LFrameIntf: IMultiViewUserFrame;
begin
  //Frame im Stand aufrufen:
  LFrameInfoLeft := FrameStand1.New<TMultiViewUserFrame>(LayoutForMVFrameLeft, 'LikeMultiViewLeft');

  LFrameIntf := LFrameInfoLeft.Frame; // Hier könnte das interface benutzt werden
  LFrameIntf.FromLeft := True;


  LFrameInfoLeft.Show;
  //Buttons en/disable
  ButtonShowLeftSide.Enabled:=false;
  ButtonSlideOutLeft.Enabled:=true;
end;
Rollo


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf