Maui: [Spec] Schlanke Renderer-Architektur

Erstellt am 19. Mai 2020  ·  56Kommentare  ·  Quelle: dotnet/maui

WARNUNG: Diese Spezifikation ist immer noch ein WIP, wir experimentieren noch mit diesem Konzept

Beschreibung

Die schlanke Renderer-Architektur profitiert von Multi-Targetting- und Einzelprojekt-Funktionen.

Beispiel

EntryRenderer.cs

public partial class EntryRenderer {
   public static PropertyMapper<IView> ViewMapper = new PropertyMapper<IView> {

     // Add your own method to map to any property         
     [nameof(IView.BackgroundColor)] = MapBackgroundColor

   };
}

EntryRenderer.iOS.cs

// You don’t need to register a new renderer.
public partial class EntryRenderer
{
     // You know what method to call because you named it!
   public static void MapBackgroundColor (IViewRenderer renderer, IView view)
     {
        // You don’t need to call any base methods here or worry about order.

        // Every renderer is consistent; you know where the native view is.
          var nativeView = (NativeView)renderer.NativeView;
          var color = view.BackgroundColor;

          if (color != null) {

            // Phew! That was easy!         
            nativeView.BackgroundColor = UIColor.FromRGB (204, 153, 255);
          }
     }
}

Standardisierung von Renderern

Alle Standard-Renderer werden für alle Plattformen auf diese Architektur portiert

Registrierung von Renderern

Der rendererRegistrar existiert im Abhängigkeitsdienst und auf den von serviceCollection.Get<IRendererRegistrar>() zugegriffen wird, ermöglicht die Kontrolle, welcher Renderer welchem ​​Steuerelement zugeordnet ist

Schnittstellen auf Renderern

Mapper-Konzept

Der Eigenschafts-Mapper ist für das Auslösen von Aktionen bei Änderungen der Antworteigenschaften verantwortlich. Ein schlanker Renderer selbst abonniert die Eigenschaftsänderungen nicht, aber einige deklarierte Aktionen werden als Reaktion auf Änderungen ausgeführt.

Die Property Mapper-Eigenschaft eines Steuerelements ist public static und kann durch Benutzercode erweitert werden.

Der Property Mapper spielt in der Feedbackschleife keine Rolle (Button angeklickt, Text eingegeben)

TODO: Besprechen Sie, was für den Mapper-Schlüssel zu verwenden ist. string oder object ? Es wäre schön, den String-Vergleich zu vermeiden, falls wir Referenzen vergleichen können (im Falle von BindableProperties).

So verwenden Sie benutzerdefinierte Legacy-Renderer

So verwenden Sie Steuerelemente von Drittanbietern in Abhängigkeit von alten Renderern

So ergänzen Sie vorhandene Renderer

Das neue Erweiterbarkeitsmodell für diese Architektur basiert auf dem Property Mapper. Wenn Sie Unterstützung für eine neue Eigenschaft hinzufügen möchten, muss nur die neue Eigenschaft zugeordnet werden. Damit die Eigenschaft vorhanden ist, ist eine Unterklasse des Steuerelements erforderlich, eine Unterklasse des Renderers jedoch nicht.

Rückwärtskompatibilität

Ob wir die Abwärtskompatibilität mit bestehenden benutzerdefinierten Renderern beibehalten wollen oder Unterklassen alter Renderer die Architektur davon beeinflussen werden

Schwierigkeit: sehr hoch

proposal-open slim renderer

Hilfreichster Kommentar

Bitte versuchen Sie nicht, um jeden Preis abwärtskompatibel zu bleiben. Das ist etwas Neues. Es muss nicht mit XF kompatibel sein. Sie können etwas besser machen.

Alle 56 Kommentare

WPF-Renderer von Xamarin-Formularen und einige Android-Renderer wie ButtonRenderer sind schnell, und wir wissen, was hier "schnell" bedeutet.
Sind diese Renderer schnell oder nicht?
Danke im Voraus.

@ysmoradi Ja ! Diese neuen Renderer folgen dem schnellen Renderer-Muster (dh keine Wrapper-Ansicht um die Hauptansicht). Wir planen, dies für alle Plattformen zu tun, nicht nur für Android und WPF.

Bitte versuchen Sie nicht, um jeden Preis abwärtskompatibel zu bleiben. Das ist etwas Neues. Es muss nicht mit XF kompatibel sein. Sie können etwas besser machen.

Warum nicht ein UI-Framework mit eigenen Steuerelementen ohne jegliche Art von Mappings und Verhaltenslogik erstellen, die vollständig auf c# geschrieben sind und mit der Skia-Grafikbibliothek gerendert werden würden? Da Menschen stark angepasstes Design verwenden, besteht keine Notwendigkeit, die Designrichtlinien der Plattform zu erfüllen. Die einzige Notwendigkeit ist die Möglichkeit der flexiblen Anpassungen. Bitte korrigieren Sie mich, wenn ich etwas vermisse, aber ich verstehe nicht, warum der Vorteil gegenüber der Renderer-Architektur liegt.

Ist es mit diesem Ansatz möglich, einen plattformübergreifenden Renderer anstelle des plattformspezifischen Renderers zu schreiben? Wie die Zuordnung der Tastensteuerung mit der Skia-Sharp-Steuerung .

Der Plattform-Renderer ist ein schlechtes Design. Wie Sie sehen, gibt es viele xamarin-Steuerelementbibliotheken, die UWP aufgrund der Plattformbeschränkung nicht unterstützen.
Nehmen Sie ein Beispiel, den Schatten in UWP. Sie können keinen Eckschatten von einer Eckschaltfläche erhalten (natürlich können Sie dazu die Schaltflächenvorlage ändern, aber das ist eine andere Sache).

Ich weiß, dass es sehr schwierig ist, ein plattformübergreifendes Rendering zu erstellen. Aber Flutter hat uns gesagt, dass dies machbar ist. Langfristig ist ein plattformübergreifender Renderer die beste Lösung.

Ich denke, das Rendern der gesamten App als benutzerdefinierte 2D-Leinwand könnte für mobile Apps nahtlos funktionieren.

Aber es funktioniert möglicherweise nicht für Desktop-Apps oder komplexe Apps, da so viele Benutzeraktionen wie Drag-Drop, Textauswahl, Tastenkombination zum Bearbeiten von Text usw. neu implementiert werden müssen.

Warum nicht ein UI-Framework mit eigenen Steuerelementen ohne jegliche Art von Mappings und Verhaltenslogik erstellen, die vollständig auf c# geschrieben sind und mit der Skia-Grafikbibliothek gerendert werden würden? Da Menschen stark angepasstes Design verwenden, besteht keine Notwendigkeit, die Designrichtlinien der Plattform zu erfüllen. Die einzige Notwendigkeit ist die Möglichkeit der flexiblen Anpassungen. Bitte korrigieren Sie mich, wenn ich etwas vermisse, aber ich verstehe nicht, warum der Vorteil gegenüber der Renderer-Architektur liegt.

Ich denke, das Rendern der gesamten App als benutzerdefinierte 2D-Leinwand könnte für mobile Apps nahtlos funktionieren.

Aber es funktioniert möglicherweise nicht für Desktop-Apps oder komplexe Apps, da so viele Benutzeraktionen wie Drag-Drop, Textauswahl, Tastenkombination zum Bearbeiten von Text usw. neu implementiert werden müssen.

Warum nicht ein UI-Framework mit eigenen Steuerelementen ohne jegliche Art von Mappings und Verhaltenslogik erstellen, die vollständig auf c# geschrieben sind und mit der Skia-Grafikbibliothek gerendert werden würden? Da Menschen stark angepasstes Design verwenden, besteht keine Notwendigkeit, die Designrichtlinien der Plattform zu erfüllen. Die einzige Notwendigkeit ist die Möglichkeit der flexiblen Anpassungen. Bitte korrigieren Sie mich, wenn ich etwas vermisse, aber ich verstehe nicht, warum der Vorteil gegenüber der Renderer-Architektur liegt.

Sie haben mit all dem absolut Recht, aber das Team ist nicht gezwungen, den einzigen Ansatz zu wählen. Ich denke, das ist alles mit Zeitmangel. Ich meine, sie müssen nur in einem Jahr zusammen mit .net 6 ein "brandneues" vollständig plattformübergreifendes UI-Framework veröffentlichen. Und es ist viel weniger riskant, ein gutes altes, bewährtes Framework als Basis zu nehmen. Es ist in Ordnung und es sollte sein. Aber ich glaube, dass benutzerdefiniertes 2D-Canvas-Rendering auf lange Sicht viel mehr Vorteile bietet und es wirklich verdient, als "plattformübergreifend" bezeichnet zu werden. Xamarin-Formulare sind wirklich eine gute Sache und haben für heute einen großen Fortschritt. Aber es ist Zeit, weiterzumachen. Microsoft- und xamarin-Teams haben sehr clevere Ingenieure und sie ziehen wahrscheinlich einen solchen Ansatz in Betracht oder haben vielleicht sogar Verbindungen zu http://avaloniaui.net/ als Trumpf

Warum nicht ein UI-Framework mit eigenen Steuerelementen ohne jegliche Art von Mappings und Verhaltenslogik erstellen, die vollständig auf c# geschrieben sind und mit der Skia-Grafikbibliothek gerendert werden würden? Da Menschen stark angepasstes Design verwenden, besteht keine Notwendigkeit, die Designrichtlinien der Plattform zu erfüllen. Die einzige Notwendigkeit ist die Möglichkeit der flexiblen Anpassungen. Bitte korrigieren Sie mich, wenn ich etwas vermisse, aber ich verstehe nicht, warum der Vorteil gegenüber der Renderer-Architektur liegt.

Es könnte cool sein, das 4. Render-Standardgrau für Skia-Entwickler zu haben, das es zu 100% ändern wird, um ein reichhaltiges Design zu liefern.
Für die Rückkämmbarkeit würde ich diese 3 so belassen wie sie sind aber füge "draw it yourself lieber Entwickler"_skia_render hinzu und übernimm 90% Verantwortung dafür Entwickler.

Wenn das Konzept der Renderer beibehalten werden soll, kann man dann daran denken, die Brücke zwischen gemeinsamem UI-Code und Renderern über INotifyPropertyChanged und Ereignishandler zu eliminieren? dh

  • Anstatt eine _property_ für das freigegebene Steuerelement festzulegen und ein PropertyChanged Ereignis weiterzugeben, kann die Eigenschaft direkt auf dem Plattform-Renderer zugeordnet und festgelegt
  • Anstatt eine _method_ für das freigegebene Steuerelement aufzurufen und ein Ereignis vom Renderer ausgelöst und verarbeitet zu werden, kann die Methode direkt auf dem Plattform-Renderer abgebildet und eingebunden

INotifyPropertyChanged eignet sich hervorragend für MVVM-Design und lose gekoppelte Ansichtsmodelle, hat sich aber als Brückenmechanismus zwischen dem gemeinsamen UI-Code und den Plattform-Renderern immer klobig angefühlt. Dies wiederum würde zu einer besseren Leistung, weniger Gesprächen zwischen der gemeinsamen Benutzeroberfläche und der Renderer-Ebene und einer besseren Entwicklererfahrung führen.

Dies ist lang, aber es lohnt sich, auf Maui nach etwas "Inside Baseball" Ausschau zu halten.
https://www.youtube.com/watch?v=_MGh3xipWm4

Es hört sich so an, als würde die Architektur von Maui sowohl von der Plattform gerenderte als auch von der Leinwand gezeichnete Steuerelemente unterstützen, und außerdem wird das edle @Clancey weiterhin an einem skia-basierten Rendering-Set für Maui arbeiten, das nicht nur in der MVU-Variante

Auf den ersten Blick schien Maui ein Rebranding von Forms zu sein, aber bei näherer Betrachtung ist es eine Umstrukturierung der Forms-Architektur, um ihre Schichten lockerer zu verbinden und dadurch viele der Dinge zu unterstützen, nach denen wir in diesem Thread fragen. Spaßige Zeiten stehen bevor.

Dies ist etwas abseits des Themas, aber ich wollte nur wegen seiner Relevanz für genau diese Sache fragen:

Wie funktioniert das Gedächtnis mit SKCanvasView (oder Skia im Allgemeinen)? Nimmt jeder Speicher immer proportional zu seiner Größe ein? Ändert sich das, wenn es sich mit anderen überschneidet?

Wenn ich zum Beispiel eine Verlaufskontrolle (Renderer in Skia geschrieben) und darüber hinaus eine halbtransparente Schaltfläche (Renderer in Skia geschrieben) hätte, würde das doppelt so viel Speicher beanspruchen oder wird der Grafikkontext irgendwie geteilt? Wie wäre es, wenn sich Skia-Steuerelemente überschneiden, die nicht von Skia stammen?

Ich habe schon einmal darüber nachgedacht, einige ausgefallene Grafiksteuerelemente in Forms mit Skia zu implementieren, aber nicht zu verstehen, wie der Speicher funktioniert, hat immer genug Bedenken verursacht, die ich nicht getan habe.

@GalaxiaGuy Ich denke, die Verwendung eines Skia-Steuerelements, das sich mit einem Nicht-Skia-Steuerelement überlappt, genau wie ein Winform-Steuerelement, das auf einem WPF-Steuerelement gehostet wird. Sie können dies tun, aber nicht das Beste.
Wenn Sie zwei Steuerelemente haben, die von SKCanvasView gerendert werden, wird der Grafikkontext nicht geteilt. Die beste Möglichkeit besteht darin, die beiden gerenderten Elemente zusammenzusetzen und auf einer einzigen Leinwand zu zeichnen.
In meinem Test ist die Leistung von SkiaSharp nicht so schlecht, wenn Sie nur ein paar statische Dinge tun. Und ich versuche, einige Animationen zu machen, die CPU-Auslastung ist auf meinem Laptop etwas hoch.

Warum sind so viele Leute von Skia besessen? Eine gute Rendering-Spezifikation wäre unabhängig von der auf der niedrigen Ebene verwendeten Rendering-Engine. Wenn ein bestimmter Plattform-Renderer Skia (oder Direct2D oder OpenGL oder was auch immer) verwenden möchte, sollte dies nichts für die Anwendungsschicht sein.

Das größte Versprechen von XAML mit WPF war vor langer Zeit die Idee von
Ich glaube nicht, dass wir noch einen weiteren Satz von Schnittstellen und Abstraktionen über vorhandene Komponenten in verschiedenen Betriebssystemen und Frameworks brauchen, sondern ein XAML-basiertes, wirklich optikloses Steuerelement – ​​mit plattformunabhängigen visuellen Primitiven und plattformspezifischen Grafik-Rendering-Backends. Und sicher, die Standardvorlage kann genauso gut die eigentliche native Steuerung sein, aber der heilige Gral sind die grafischen Vorlagen, die Sie einmal überall verwenden können.

Das größte Versprechen von XAML mit WPF war vor langer Zeit die Idee von Lookless Controls, bei denen die eigentlichen Grafiken der Controls auf Vorlagen verschoben wurden. Xamarin Forms verwendete XAML ohne diese Fähigkeit, und dies war der schwächste Punkt, der erst Jahre später teilweise durch die Zeichnungsspezifikation behoben wurde.

Einverstanden! Und Sie benötigen wirklich eine sehr kleine Anzahl von Rendering-Primitiven, um wahrscheinlich 99% von allem zu erreichen, was eine App benötigt:

  • Ränder (inkl. Optionen für Schlagschatten und abgerundete Kanten)
  • Linien/Ellipsen/Rechtecke
  • Klartext-Rendering
  • Klartexteingabe
  • Rich-Text-Rendering
  • Rich-Text-Eingabe
  • HTML-Rendering
  • Bildpräsentation
  • Audio-/Video-Moderatorin
  • Einfarbige und lineare / radiale Verlaufspinsel

Die XF-Rendering-Plattformen sind so aufgebläht, dass jedes Mal, wenn eine neue Art von Steuerelement zum Framework hinzugefügt wird, dies mit einem neuen Renderer geschieht, anstatt auf bestehenden Primitiven innerhalb des Frameworks aufzubauen.

Ja, es müsste viel mehr Logik in die Framework-Schicht verschoben werden, die größte Herausforderung besteht darin, wenn es um die Elementsteuerung geht ( VirtualizingStackPanel ist entscheidend für einen skalierbaren Artikelbetrachter, wurde aber meines Wissens noch nie effektiv nach außen portiert von WPF, weil es so komplex ist). Aber da WPF Open Source ist, kann vieles davon jetzt in MAUI portiert werden und ich denke, dies ist endlich der Zeitpunkt, an dem dies geschehen sollte.

Sie benötigen wirklich eine sehr kleine Anzahl von Rendering-Primitiven, um wahrscheinlich 99% von allem zu erreichen, was eine App benötigt.

Die Uno-Plattform verwendet diesen Ansatz.

@velocitysystems

Anstatt eine Eigenschaft für das freigegebene Steuerelement festzulegen und ein PropertyChanged-Ereignis weiterzugeben, kann die Eigenschaft direkt im Plattformrenderer zugeordnet und festgelegt werden?

Das ist auch ein großes Ziel dieser Änderung. Sobald wir auf der anderen Seite dieser Änderungen sind, haben die Renderer keine Ahnung, was ein BindableObject oder INPC bedeutet

Das ist auch ein großes Ziel dieser Änderung. Sobald wir auf der anderen Seite dieser Änderungen sind, haben die Renderer keine Ahnung, was ein BindableObject oder INPC bedeutet

Also wird eine Methode im Renderer vom Framework aufgerufen, wenn sich ein BindableProperty Wert ändert, anstatt dass der Renderer PropertyChanged abonnieren muss?

@legistek richtig

Dies invertiert im Grunde die Abhängigkeiten

Die Renderer funktionieren also nur gegen IButton.

Und dann fügt System.Maui einen Verweis auf das Renderer-Projekt hinzu, im Gegensatz zu den Renderern, die Verweise auf Xamarin.Forms.Core haben

Ich habe einen Spike eingecheckt, den wir hier haben
https://github.com/dotnet/maui/pull/66

So können Sie sehen, wie das aussehen könnte

Ich mache heute um 15:30 Uhr PDT einen Stream mit @davidortinau und wir sprechen über die schlanken Renderer

https://www.twitch.tv/microsoftdeveloper

Begleiten Sie uns! Hör zu! Und stellen Sie Fragen!

@PureWeen Leider habe ich es verpasst. Wird es eine Aufnahme auf YouTube geben?

Das ist auch ein großes Ziel dieser Änderung. Sobald wir auf der anderen Seite dieser Änderungen sind, haben die Renderer keine Ahnung, was ein BindableObject oder INPC bedeutet.

Das ist enorm, eine wirklich wesentliche Verbesserung. Zweifellos wird mit dem Umzug nach Maui auch das komplexe Vererbungsmodell, das in vielen Renderern verwendet wird, zugunsten eines kompositorischeren Ansatzes entfernt?

Werde heute #66 rezensieren.

Wenn man sich #66 ansieht, ist es schön zu sehen, dass die schlanken Renderer mit 'bait-and-switch' gebaut und aufgerufen werden, anstatt Reflektion zu verwenden. Nur ein paar Gedanken:

  • Werden Slim-Renderer die GC-Probleme beheben, insbesondere auf Android, wo eine Diskrepanz zwischen dem verwalteten und dem nativen Steuerungslebenszyklus besteht? Dies macht sich besonders in untergeordneten Ansichten in virtualisierten Layouts bemerkbar, was zu dem gefürchteten ObjectDisposedException .
  • Werden Slim-Renderer dazu führen, dass Effect ? Effekte können nützlich sein, aber letztendlich erhöhen sie die Komplexität und ein weiteres Potenzial für Latenzzeiten im Layout-Lebenszyklus.
  • Wie würde eine Zwei-Wege-Eigenschaft mit dem neuen Renderer-Design funktionieren? Angenommen, ich habe ein MediaElement mit einer Position ( TimeSpan ) Eigenschaft. Setter aktualisiert die aktuelle Position, und der Getter ruft die aktuelle Position vom nativen Mediaplayer ab, dh AVPlayer , MediaPlayer . Gibt es ein Design für das Mapping eines _getter_ mit schlanken Renderern?

Werden Slim-Renderer die GC-Probleme beheben, insbesondere auf Android, wo eine Diskrepanz zwischen dem verwalteten und dem nativen Steuerungslebenszyklus besteht? Dies macht sich besonders in untergeordneten Ansichten in virtualisierten Layouts bemerkbar, was zu der gefürchteten ObjectDisposedException führt.

Wir haben hier einige Ideen!! Wir wollen die Entsorgungsstrategien ein wenig überarbeiten, um hoffentlich die meisten, wenn nicht alle ODE-Ausnahmen zu beheben. Im Moment entsorgen wir alles in Android/iOS sehr aggressiv, aber ich bin mir ziemlich sicher, dass wir uns einfach darauf verlassen können, dass der GC das tut, was der GC tut. Wenn wir einfach alles dereferenzieren und den GC die Arbeit machen lassen, sollte das in vielen dieser Fälle helfen

Werden Slim-Renderer dazu führen, dass Effect verworfen wird? Effekte können nützlich sein, aber letztendlich erhöhen sie die Komplexität und ein weiteres Potenzial für Latenzzeiten im Layout-Lebenszyklus.

Dies ist definitiv eine gute Sache, die wir uns bei der Entwicklung dieser Idee ansehen sollten. Sobald wir ein endgültiges Design für all dies erreicht haben, werden wir uns die Effekte ansehen. Aber ja, ich konnte sehen, dass Effekte veraltet sind, da sie als Möglichkeit gedacht sind, native Elemente zu nutzen, ohne den vollständigen Renderer verwenden zu müssen. Mapper im Grunde veraltete Effekte

Wie würde eine Zwei-Wege-Eigenschaft mit dem neuen Renderer-Design funktionieren? Angenommen, ich habe ein MediaElement mit einer Position (TimeSpan)-Eigenschaft. Der Setter aktualisiert die aktuelle Position, und der Getter ruft die aktuelle Position vom nativen Mediaplayer ab, dh AVPlayer, MediaPlayer. Gibt es ein Design für das Mapping eines Getters mit schlanken Renderern?

Wir arbeiten noch ein bisschen daran. Korrigiert mich, wenn ich falsch liege @Clancey, aber der ActionMapper war unser aktueller Ansatz dafür, ja? https://github.com/dotnet/maui/blob/slim-renderers/Maui.Core/PropertyMapper.cs#L91

Wie würde eine Zwei-Wege-Eigenschaft mit dem neuen Renderer-Design funktionieren? Angenommen, ich habe ein MediaElement mit einer Position (TimeSpan)-Eigenschaft. Der Setter aktualisiert die aktuelle Position, und der Getter ruft die aktuelle Position vom nativen Mediaplayer ab, dh AVPlayer, MediaPlayer. Gibt es ein Design für das Mapping eines Getters mit schlanken Renderern?

Wir arbeiten noch ein bisschen daran. Korrigiert mich, wenn ich falsch liege @Clancey, aber der ActionMapper war unser aktueller Ansatz dafür, ja? https://github.com/dotnet/maui/blob/slim-renderers/Maui.Core/PropertyMapper.cs#L91

Nicht genau. Der ActionMapper ist also dasselbe wie ein PropertyMapper mit der Ausnahme, dass er während der SetElement-Phase nicht aufgerufen wird. Also für Dinge wie WebView, GoBack. Sie möchten das während der Initialisierung nicht aufrufen, aber es ist immer noch etwas, das Sie mit dem Renderer kommunizieren müssen.

Wir unterstützen bereits 2-Wege-Mapping. dh Eintrag. Wenn der Textwert zufällig auf den Eintrag fällt. der IEntry hat ein string Text {get;set;} und wir setzen einfach den Wert. Für Medienelemente haben Sie also 2 Möglichkeiten. Man setzt einfach die Position/Zeit zurück, wenn sie sich ändert. Wenn Sie es zu etwas machen möchten, fragen Sie stattdessen ab. Das kannst du machen. Die xplat-Ansichten haben Zugriff auf den Renderer. view.Renderer.NativeView as NativeMediaView Sie können jetzt alle gewünschten Eigenschaften erstellen!

Hier sind einige Videos aus unseren Streams während des Builds

@Clancey wird hier ausführlicher sein
https://www.youtube.com/watch?v=_MGh3xipWm4

Ich berühre sie hier mit David ein wenig
https://www.youtube.com/watch?v=lAmwjfZY1IM

Wie würde eine Zwei-Wege-Eigenschaft mit dem neuen Renderer-Design funktionieren? Angenommen, ich habe ein MediaElement mit einer Position (TimeSpan)-Eigenschaft. Der Setter aktualisiert die aktuelle Position, und der Getter ruft die aktuelle Position vom nativen Mediaplayer ab, dh AVPlayer, MediaPlayer. Gibt es ein Design für das Mapping eines Getters mit schlanken Renderern?

Wir arbeiten noch ein bisschen daran. Korrigiert mich, wenn ich falsch liege @Clancey, aber der ActionMapper war unser aktueller Ansatz dafür, ja? https://github.com/dotnet/maui/blob/slim-renderers/Maui.Core/PropertyMapper.cs#L91

Nicht genau. Der ActionMapper ist also dasselbe wie ein PropertyMapper mit der Ausnahme, dass er während der SetElement-Phase nicht aufgerufen wird. Also für Dinge wie WebView, GoBack. Sie möchten das während der Initialisierung nicht aufrufen, aber es ist immer noch etwas, das Sie mit dem Renderer kommunizieren müssen.

Wir unterstützen bereits 2-Wege-Mapping. dh Eintrag. Wenn der Textwert zufällig auf den Eintrag fällt. der IEntry hat ein string Text {get;set;} und wir setzen einfach den Wert. Für Medienelemente haben Sie also 2 Möglichkeiten. Man setzt einfach die Position/Zeit zurück, wenn sie sich ändert. Wenn Sie es zu etwas machen möchten, fragen Sie stattdessen ab. Das kannst du machen. Die xplat-Ansichten haben Zugriff auf den Renderer. view.Renderer.NativeView as NativeMediaView Sie können jetzt alle gewünschten Eigenschaften erstellen!

Eine andere Sache, die Sie hier berücksichtigen sollten, sind Datensätze, die in C#9 erscheinen. Die Besonderheit besteht darin, dass sie unveränderlich sind und den Eigenschafts-Accessor init . Um sie also in einer bidirektionalen Bindung nutzbar zu machen, muss der Mapper in der Lage sein, eine neue Instanz mit dem with Operator zurückzugeben.

Ich hoffe wirklich, dass Ansichten an Datensätze gebunden werden können, da dies vieles einfacher macht, wenn es um reine MVVM oder sogar reine MVU geht.

Frage: In dem von Ihnen geposteten Diagramm werden die Windows-Steuerelemente von Windows.UI.* gerendert, aber wie ich es verstanden habe, wird dies jetzt veraltet und es werden keine Updates angezeigt: Alle Verbesserungen an den fließenden Design-Renderings sind findet in Microsoft.UI.* als Teil des WinUI-Projekts statt. Können Sie das bitte kommentieren?

Ich denke, die Zuordnung zu nativen Steuerelementen ist ein großer Fehler, dies ist der schreckliche Teil von Xamarin.Forms, Sie können nicht einfach einzigartige und schöne Layouts erstellen, Sie mussten dem Konzept und dem Ansatz von WPF- und Flutter-Steuerelementen ohne Erscheinungsbild mit einem Rendering folgen in C++ geschriebene Engine mit OpenGL / DirectX / Metal, da dies Portabilität, Leistung und Flexibilität erleichtert und nicht von sich ständig ändernden Plattformstrukturen abhängig ist.

Das Thema ist hier, um über die neuen Architecture/ Property Mapper zu sprechen. Nicht das, was sie abbilden. Nur um es noch einmal zu wiederholen. Slim Render Architecture für native bedeutet nicht, dass wir niemals einen Draw-Control-Ansatz durchführen werden und können. Dies ermöglicht es uns jedoch, native und nicht-native Steuerelemente zu mischen und abzugleichen, wobei es schwieriger ist, rein gezeichnet zu werden. Ich habe vor, weiterhin an Skia-basierten Steuerelementen zu arbeiten, die der gleichen Slim-Renderer-Architektur folgen, einschließlich der Zeichenebene. https://github.com/Clancey/Comet/tree/dev/src/Comet.Skia/Handlers.

Meine 2¢ zu dieser Renderer-Sache (was ich zugebe, dass ich es nicht ganz verstehe, TBH):

Ich hatte eine Idee, wie wir sowohl plattformgerenderte Controls (zB Wrapping UIButton) als auch Lookless Controls (a la WPF) mit derselben Control-Klasse implementieren könnten. Es ist ganz einfach, ehrlich gesagt: Lassen Sie die Maui Button-Klasse eine Steuerelementvorlage verwenden und entfernen Sie den gesamten plattformspezifischen Renderer-Code daraus. Stellen Sie dann eine Posteingangsvorlage für Button bereit, die einen ButtonRenderer enthält. Der ButtonRenderer kommuniziert mit Cocoa/UIKit/UWP/etc, mit plattformspezifischem Code für jedes UI-Toolkit, und die vom App-Entwickler verwendete Button-Klasse leitet einfach ihre Eigenschaften an ihn weiter. Wenn der Benutzer eine benutzerdefinierte Schaltfläche verwenden möchte, kann er einfach die Vorlage überschreiben und Zeichenklassen (wie auch immer das letztendlich aussehen mag) anstelle des ButtonRenderer verwenden, genau wie wir es in WPF tun. Ich weiß ehrlich gesagt nicht, ob dies in Maui heute bereits möglich (oder sogar bereits verwendet) ist, da ich mir nie die Zeit genommen habe, Xamarin.Forms so tief zu verstehen, wie ich WPF verstehe.

Sag mir was du denkst!

Ich versuche zu verstehen, was Slim-Renderer für verschiedene App-Modelle (MVVM, MVU, ...) bedeuten würden.

Das anfängliche Diagramm scheint zu sagen, dass jedes unterschiedliche App-Modell seinen eigenen Satz von Renderern hat.
Aber meiner Meinung nach wäre es besser, einen Satz Renderer pro Rendering-Typ zu haben (zB Rendern in native Steuerelemente wie XF, Rendern in Canvas usw.).
Der Renderer muss das App-Modell nicht kennen, er muss nur wissen, welcher Wert welcher Eigenschaft zugeordnet ist, damit er das richtige Update auf das zugrunde liegende Steuerelement anwenden kann.
Nur IButton wird für jedes App-Modell unterschiedlich implementiert und ist für den Aufruf der zugeordneten Funktionen seines Renderers verantwortlich.

Dies ist wichtig, da Bibliotheken von Drittanbietern wie Fabulous nicht die Arbeitskraft von Microsoft haben, um (mit all den damit verbundenen Fehlern) alle geeigneten Renderer für jedes Steuerelement auf jeder Plattform zu implementieren.

Ein weiterer Punkt ist: Die Steuerschnittstellen ( IButton ) sollten nur getter sein, damit sie von den Renderern verwendet werden.
Renderer legen keine Werte fest und jedes App-Modell gestaltet die Steuerelemente anders (BindableProperty, BindingObject usw.).
Fabulous hat beispielsweise unveränderliche Ansichten. Nur intern ist es berechtigt, die Mutation auf die Instanz von IButton .

Auf diese Weise könnte Fabulous die IButton Schnittstelle direkt als Leseransicht über sein internes Wörterbuch verwenden, damit die Renderer arbeiten können.

// This is the type used by our users, sort of a Builder that return a new instance each time
// and append the set value to an internal list 
public struct Button
{
     public Button Text(string value) => (...);

     internal ReadOnlyDictionary<string, obj> Build() { ... }
}

// This will be an implementation of IButton, hidden from our users
internal class FabulousButton : IButton
{
    private ReadOnlyDictionary<string, obj> _properties;
    FabulousButton(ReadOnlyDictionary<string, obj> properties)
    {
        _properties = properties;
    }

    void Update(ReadOnlyDictionary<string, obj> properties)
    {
        var previousProperties = _properties;
        _properties = properties;

        // Diffing of the 2 dictionaries to determine what changed
        // and which mapped functions inside the renderer should be called
        (...)
    }

    public string Text => _properties["Text"];
}

@TimLariviere Alles, was du gesagt hast, ist, wie es funktioniert :-)

Die Zeichnung dort ist bis auf die Renderer verwirrend.

Der einzige Teil, um den Sie sich kümmern müssen, ist der Fabulous Button und dann kümmern wir uns um alles andere

Die Schnittstellen sind größtenteils readonly

Dies ist die Schnittstelle, die von button . verwendet wird
https://github.com/dotnet/maui/blob/slim-renderer-samples/Maui.Core/Views/IText.cs

Alles, was wirklich an Ihnen liegt (was die Renderer angeht), ist dem Renderer zu signalisieren, dass er den IButton wieder verwenden soll

In der BindableObject-Version von all dem rufen wir beispielsweise hier nur die updateproperty-Methode des Renderers auf

https://github.com/dotnet/maui/blob/slim-renderer-samples/System.Maui.Core/VisualElement.cs#L1132

Irgendwann (bald?) wird @Clancey eine öffentliche Version von Comet haben, die Sie sich ansehen können, um zu sehen, wie er es macht.

ich würde auschecken
https://github.com/dotnet/maui/blob/slim-renderer-samples

Sie können wahrscheinlich Ihren eigenen Fabulous.Core-Kopf hinzufügen und dann mit dem Hinzufügen von Implementierungen zu den Schnittstellen beginnen

@PureWeen Oh cool. Danke, ich werde versuchen, mit den von Ihnen verlinkten Samples zu spielen, um zu sehen, wie es geht.

@PureWeen @Clancey Ich bin mir sicher, dass das Maui-Team das alles übernehmen wird, aber bitte können die neuen Slim-Renderer die Komposition der Vererbung

@PureWeen
Diese URL
https://github.com/dotnet/maui/blob/slim-renderer-samples

gibt 404, ist es privat?

@Rand-Random

https://github.com/dotnet/maui/tree/slim-renderer-samples

@velocitysystems

Ich bin sicher, das Maui-Team wird sich damit befassen, aber können die neuen Slim-Renderer bitte die Komposition der Vererbung vorziehen. Vererbung ist nützlich, aber leider hat sie in XF einige der Renderer-Hierarchien unglaublich komplex und schwer zu pflegen gemacht.

So sind sie aufgebaut. Es gibt eine sehr dünne Basisklasse, die direkt vom guten alten System.Object erbt

https://github.com/dotnet/maui/blob/slim-renderer-samples/Maui.Core/Renderers/View/AbstractViewRenderer.Android.cs

Und hat keine einheimischen Bindungen.

Von da an wird das Ganze durch das definiert, was im Grunde ein Wörterbuch ist

https://github.com/dotnet/maui/blob/slim-renderer-samples/Maui.Core/Renderers/View/AbstractViewRenderer.cs#L31

Was im Grunde wie ein Dekorateur funktioniert.

Sie können Mapper mit zusätzlichen Mappern dekorieren und Sie können Ihre eigenen Func's usw. einfügen.

Wir streben an, 95 Prozent der Benutzerszenarien abzudecken, indem Sie einfach Ihre eigene Func zum Mapper hinzufügen oder einfach direkt auf die nativen Elemente zugreifen, da alles auf mehrere Ziele ausgerichtet ist

@PureWeen Was wäre der am besten geeignete Kanal, um die Implementierung dieser schlanken Renderer in Ihrem Beispiel zu diskutieren?

Ich habe einige Fragen wie:

  • Werden die Standardwerte an einer zentralen Stelle definiert? In XF werden sie derzeit beim Erstellen der BindableProperty-Felder definiert, diese sind jedoch je nach App-Modell nicht vorhanden.
  • Wird die Application-Klasse auch (teilweise) ein Interface? Es definiert viele UI-Verhalten (Ressourcen, Menü, Hauptseite) und wäre großartig, um es anders zu implementieren.
  • Wird Messen/Anordnen/usw. aus den Steuerschnittstellen extrahiert? Ich glaube nicht, dass es für App-Modelle wirklich sinnvoll ist, sie anders zu implementieren.

Werden die Standardwerte an einer zentralen Stelle definiert? In XF werden sie derzeit beim Erstellen der BindableProperty-Felder definiert, diese sind jedoch je nach App-Modell nicht vorhanden.

Dies ist eine gute Frage. @Clancey ? Ich bin mir nicht sicher, ob wir das noch definiert haben. Es gibt eine anfängliche Einrichtungsphase, in der alle Mapper mit dem aktuellen Wert der Eigenschaften (Standardwert) aufgerufen werden, aber ich bin mir nicht sicher, ob wir noch einen Plan für Standardwerte haben und wie diese verallgemeinert werden

Wird die Application-Klasse auch (teilweise) ein Interface? Es definiert viele UI-Verhalten (Ressourcen, Menü, Hauptseite) und wäre großartig, um es anders zu implementieren.

Jawohl! Wir hoffen, alle Anwendungsklassen (native und xplat) in einer einzigen Anwendungsklasse zusammenfassen zu können. Warum fragst du danach? Ich bin nur neugierig auf Ihren Anwendungsfall hier, damit wir sicherstellen können, dass Sie ihn ansprechen

Wird Messen/Anordnen/usw. aus den Steuerschnittstellen extrahiert? Ich glaube nicht, dass es für App-Modelle wirklich sinnvoll ist, sie anders zu implementieren.

An dieser Stelle ist das der Plan. Die Idee ist, unseren gesamten Layout-Code zu extrahieren, damit nichts davon von BindableObject/Property abhängt. Auf diese Weise können Blazor/Comet/andere einfach ein StackLayout verwenden und das Ergebnis ist das gleiche.

Warum fragst du danach? Ich bin nur neugierig auf Ihren Anwendungsfall hier, damit wir sicherstellen können, dass Sie ihn ansprechen

Ich bin mir noch nicht ganz sicher, was ich will. Aber in Fabulous haben wir derzeit keine gute Geschichte zum Definieren globaler Stile und des Hauptmenüs (wie für macOS). Da wir unseren Benutzern erlauben, die Application-Klasse selbst unterzuordnen, weisen wir sie im Grunde an, Ressourcen/Menüs wie im klassischen Xamarin.Forms zu definieren.

Idealerweise wären also alle UI-bezogenen Eigenschaften von Application auch Teil der Ansicht, sodass wir unsere Ansichtsdifferenzierungslogik auch darauf anwenden könnten.

Sowas in der Art

public interface IAppRoot
{
    IEnumerable<object> Resources { get; }
    IMenu MainMenu { get; }
    IPage MainPage { get; }
}

public class Application
{
    /// Bootstrapping and other logic of MAUI

   public IAppRoot Root { get; set; } // Replaces MainPage, which is typed for pages only
}

@PureWeen Eine weitere Frage: Wer ist für das Auslösen von Ereignissen wie TextChanged , Toggled usw. verantwortlich? Die Steuerelemente oder die Renderer?

Eine Sache, die meiner Meinung nach die Implementierung anderer App-Modelle erheblich vereinfachen würde, ist die Möglichkeit, keine zustandsändernden Ereignisse auszulösen, wenn Änderungen programmatisch sind.

Heute beispielsweise wird TextChanged on Entry ausgelöst, wenn der Benutzer etwas schreibt oder wenn wir MyEntry.Text = "New value"; tun.
Ich denke, auf eine programmatische Änderung zu reagieren, ist nicht wirklich nützlich und implizit, was schlecht für die Argumentation des Codes ist.

Auch dies führte zu einer Endlosschleife auf Android, da die Plattform ihre Ereignisse mit einer leichten Verzögerung auslöst und Fabulous gezwungen wurde, nicht mehr synchron zu sein, ohne dass eine Rückkehr möglich war.
Die einzige Problemumgehung, die wir gefunden haben, bestand darin, das Ereignis zuerst abzubestellen, bevor Sie den Wert festlegen und dann erneut abonnieren ...

Eine kuriose Frage. Wenn MAUI architekturunabhängig ist, warum werden die Steuerelemente nach Architekturnamen benannt? Zum Beispiel Im obigen Diagramm haben wir Maui. Mvvm .ButtonRenderer.Android? @PureWeen @Clancey

XF hat etwas namens Compressed Layouts (was fehlerhaft ist)
Haben wir so etwas (mit Sicherheit ohne Bugs!) in MAUI?

Ich sehe, wie die Leute in diesem Thread auf den Flutter / Skia-Ansatz zum Rendern der Benutzeroberfläche reagieren, und ich stimme ihnen größtenteils zu.
Ich bin wirklich froh, dass MAUI möglicherweise benutzerdefinierte/nicht native Steuerelemente und Renderings unterstützt.
Allerdings muss ich sagen, dass die Möglichkeit, mit nativer UI zu arbeiten, den Rahmen auf politischer Seite sichert.
Und ja, ich weise auf Apple hin. Aufgrund der neuesten Nachrichten würde es mich nicht wundern, wenn die Verwendung von Flutter irgendwann aus irgendeinem Grund als "Ausnutzung nicht dokumentierter/eingeschränkter Funktionen" oder "Nichtbefolgen der Apple-UI-Richtlinien" usw. angesehen würde.

Ich sehe, wie die Leute in diesem Thread auf den Flutter / Skia-Ansatz zum Rendern der Benutzeroberfläche reagieren, und ich stimme ihnen größtenteils zu.
Ich bin wirklich froh, dass in MAUI möglicherweise benutzerdefinierte/nicht native Steuerelemente und Renderings unterstützt werden.
Allerdings muss ich sagen, dass die Möglichkeit, mit nativer UI zu arbeiten, den Rahmen auf politischer Seite sichert.
Und ja, ich weise auf Apple hin. Aufgrund der neuesten Nachrichten würde es mich nicht wundern, wenn die Verwendung von Flutter irgendwann aus irgendeinem Grund als "Ausnutzung nicht dokumentierter/eingeschränkter Funktionen" oder "Nichtbefolgen der Apple-UI-Richtlinien" usw. angesehen würde.

Wenn MAUI das Web unterstützt (wie Flitter), können wir immer in WebView rendern.
Es ist unwahrscheinlich, dass Apple es jemals wagen wird, WebView-basierte Anwendungen zu blockieren, da einige große Unternehmen im AppStore nur über WebView vertreten sind

Ich sehe, wie die Leute in diesem Thread auf den Flutter / Skia-Ansatz zum Rendern der Benutzeroberfläche reagieren, und ich stimme ihnen größtenteils zu.
Ich bin wirklich froh, dass in MAUI möglicherweise benutzerdefinierte/nicht native Steuerelemente und Renderings unterstützt werden.
Allerdings muss ich sagen, dass die Möglichkeit, mit nativer UI zu arbeiten, den Rahmen auf politischer Seite sichert.
Und ja, ich weise auf Apple hin. Aufgrund der neuesten Nachrichten würde es mich nicht wundern, wenn die Verwendung von Flutter irgendwann aus irgendeinem Grund als "Ausnutzung nicht dokumentierter/eingeschränkter Funktionen" oder "Nichtbefolgen der Apple-UI-Richtlinien" usw. angesehen würde.

Wenn MAUI das Web unterstützt (wie Flitter), können wir immer in WebView rendern.
Es ist unwahrscheinlich, dass Apple es jemals wagen wird, WebView-basierte Anwendungen zu blockieren, da einige große Unternehmen im AppStore nur über WebView vertreten sind

das verstößt bereits gegen die Richtlinien - https://developer.apple.com/app-store/review/guidelines/#minimum -functionality

Nachdem ich ein bisschen hin und her gelesen habe, was diese ganz neue Welt von MAUI zu sein scheint, bitte aus Liebe zu allem, was heilig ist, tatsächlich eine Write-Once-Render-Engine wie SKIA oder eine andere Multiplattform-Rendering-Engine verwenden, die benutzerdefinierte implementieren muss Die Benutzeroberfläche auf jeder Plattform wie in Xamarin Forms fühlt sich alt an und als wäre es eine Lösung, die im siebten Kreis der Hölle erstellt wurde.

Wenn Abwärtskompatibilität ein Muss ist, "nur" die neue und moderne Render-Unterstützung zu einer Möglichkeit zu machen, ältere Komponenten zu rendern, habe ich gesehen, dass andere Plattformen eine nette Lösung dafür haben das neue moderne UXML hat einen IMGUI Render.

@jackie0100
Ich stimme vollkommen zu

auf jeder Plattform eine benutzerdefinierte Benutzeroberfläche wie in Xamarin Forms implementieren zu müssen, fühlt sich alt an und wie eine Lösung, die im siebten Kreis der Hölle erstellt wurde.

Was die Renderer-Implementierung angeht, was ist mit der Idee einer IView IS A native View (anstelle einer IView HAS A native View). dh Vererbung statt Komposition? Dies würde zu der schnellsten und schlanksten Architektur mit absolut keinem "Formular Overhead" führen. Sie arbeiten im Grunde mit reinen nativen Ansichten und nur einer gemeinsamen Oberfläche.

Dann könnten Sie im iOS-Land beispielsweise Ihre Ansicht in eine UIView umwandeln und ihr ein natives untergeordnetes Element hinzufügen (jeden gewünschten Typ), da eine IView eine UIView ist. Wenn Sie "natives Einbetten" durchführen möchten, ist dies ebenfalls einfach, da ein IView ein UIView ist. Sie können einfach eines Ihrer IViews zu Ihrer nativen Ansicht hinzufügen, da es sich um dasselbe handelt. Dies würde die native <-> Maui-Interoperabilität massiv ermöglichen, und das bei höchster Leistung und geringstem Speicherverbrauch.

Ich habe irgendwie Lust, das selbst zu prototypieren. Vielleicht ein Wochenend-/Abendprojekt...

image

Wenn MAUI das Web unterstützt (wie Flitter), können wir immer in WebView rendern.

WebView auf iOS nicht erforderlich: kann direkt in OpenGL oder Metal rendern.

Oder verwenden Sie Skia mit OpenGL oder Metal darunter.

Die Fähigkeit, mit nativer Benutzeroberfläche zu arbeiten, sichert den Rahmen auf der politischen Seite der Dinge. [Apfel]

Irgendwann hat Apple die Anforderung, native UI-Widgets zu verwenden, aus seiner schriftlichen Richtlinie gestrichen. Ich sehe keine praktische Möglichkeit, die Politik wieder restriktiv zu machen.

Unabhängig davon ist es eine gute Option, mit nativen Steuerelementen arbeiten zu können.

@legistek

Warum sind so viele Leute von Skia besessen? Eine gute Rendering-Spezifikation wäre agnostisch für die Rendering-Engine ...

Obwohl ich absolut zustimme, "agnostisch" zu sein, müssen viele Details implementiert werden, um eine interaktive Benutzeroberfläche zu rendern - wenn Sie direkt zu OpenGL/Metal/Vulkan/was auch immer Low-Level-Rendering-Engine wechseln. Die Leute sind von Skia besessen, weil es eine effektive _mittlere Schicht_ zwischen den UI-Anliegen der App und der eigentlichen Rendering-Engine ist: Skia übernimmt _viel_ von dem, was entworfen und implementiert werden müsste, wenn Sie nur blankes Metall haben. Kein Grund, diese Arbeit neu zu erfinden. Obwohl es nicht das _einzige_ Ziel sein sollte, ist es ein äußerst wertvolles und ausgereiftes Ziel, das es beispielsweise viel einfacher macht, von OpenGL zu Vulkan zu wechseln.

Ich vermute auch, dass das Targeting auf Skia viel weniger umständlich wäre als die Xamarin Forms-Pflege von zwei parallelen Widget-Hierarchien – den plattformübergreifenden Widgets und den nativen Widgets.

Skia könnte sogar den Tag beschleunigen, an dem .Net Maui im Browser hochperformant ist. Auch hier, denn anstatt auf einer niedrigen Ebene aufzubauen, beginnen Sie beim Rendern mit einer geeigneten Abstraktion auf mittlerer Ebene. Das wäre ein Riesengewinn.

Hallo zusammen, vergesst es nicht:
https://github.com/dotnet/maui/discussions/103

Nachdem ich die letzten Maui-Videos gesehen habe, scheint es, wenn ich mich nicht irre, zu mehr gestylten Steuerelementen zu kommen, wobei die native Steuerung mit Zeichnungen auf der plattformunabhängigen Seite überlagert wird. Ob Skia oder eine Art Batch-Interop zu nativen Canvas-Zeichnungen, ich hoffe, dieser Ansatz wird verfolgt! Das Renderer-Modell der XF-Plattform hat den Microsoft-UI-Plattformen ironischerweise immer am meisten geschadet, da es am wenigsten verwendet wird.

Ich würde auch die Möglichkeit offen lassen, dass ein Steuerelement explizit keine native Komponente hat und der Layout-Compositor dies erkennt skia, es könnte den Container zu einem SkView machen und einfach die Zeichenoperation für die untergeordneten Steuerelemente des Labels aufrufen), auf Android würde dies beispielsweise bei Listenelementen mit vielen Bildern + Textsteuerelementen einen Geschwindigkeitsschub geben.

Ich verstehe nicht, was ein Renderer ist.
Wenn das Programm zum Absorbieren der visuellen Unterschiede des Ziels als Renderer bezeichnet wird, sollte es von Xamarin und MAUI insgesamt absorbiert werden. Wenn nicht, denke ich, dass es ein unfertiges Xamarin und MAUI ist. Und es wird nie fertiggestellt.
Ich denke, die Anwendungsprogrammierung sollte unabhängiger von den Unterschieden in der Zielumgebung sein.

Ich verstehe nicht, was ein Renderer ist.
Wenn das Programm zum Absorbieren der visuellen Unterschiede des Ziels als Renderer bezeichnet wird, sollte es von Xamarin und MAUI insgesamt absorbiert werden. Wenn nicht, denke ich, dass es sich um ein unfertiges Xamarin und MAUI handelt. Und es wird nie fertig.
Ich denke, die Anwendungsprogrammierung sollte unabhängiger von den Unterschieden in der Zielumgebung sein.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

probonopd picture probonopd  ·  50Kommentare

Yaroslav08 picture Yaroslav08  ·  6Kommentare

PureWeen picture PureWeen  ·  21Kommentare

Amine-Smahi picture Amine-Smahi  ·  3Kommentare

njsokalski picture njsokalski  ·  6Kommentare