Erstellen eines neuen Xamarin.Forms-Element mit Renderern
Das Ableiten von vorhandenen Renderern und Verbessern ihres integrierten Verhaltens funktioniert hervorragend, wenn ein Xamarin.Forms-Element vorhanden ist, das bereits das meiste von dem erledigt, was wir brauchen. Aber wenn wir ein Steuerelement wünschen, das in Xamarin.Forms überhaupt noch nicht vorhanden ist, unterscheiden sich die Schritte geringfügig, und ein wenig mehr Arbeit ist zu tun.
Wir benötigen ein Xamarin.Forms-Element und einen Renderer. Außerdem benötigen wir ein natives Steuerelement, das auf jeder Plattform verwendet werden kann. Wir möchten z.B. ein Steuerelement, das dem Benutzer ermöglicht, auf dem Bildschirm zu zeichnen, aber weder in iOS noch in Android ist ein solches integriertes natives Steuerelement vorhanden. Wir müssen es also entweder erstellen oder Drittanbieterimplementierungen in beiden Plattformen suchen.
In dieser Unterrichtseinheit werden wir ein benutzerdefiniertes Xamarin.Forms-Element und einen Renderer zum Erstellen einer Zeichen-App erstellen.
Erstellen eines Elements
Beim Anpassen eines Elements und eines Renderers haben wir die vorhandene Implementierung als Basisklasse verwendet. Jetzt erstellen wir aber ein ganz neues Element. Da View
das einfachste Xamarin.Forms-Element ist, verwenden wir es als Basisklasse für das neue Element:
public class SketchView : View
{
...
}
Hinzufügen von Elementeigenschaften
Die meisten Elemente haben einige Konfigurationsoptionen oder Werte, die mit dem nativen Steuerelement gemeinsam genutzt werden müssen. Integrierte Steuerelemente haben tendenziell zu viele Eigenschaften, die festgelegt werden können. Label
hat beispielsweise Text
, FontSize
und viele andere. Für benutzerdefinierte Elemente müssen wir entscheiden, welche Eigenschaften sinnvoll sind. Unsere Implementierung von SketchView
verfügt z.B. über eine InkColor
-Eigenschaft zum Ändern der Farbe der Linie, die wir zeichnen.
Wenn wir Eigenschaften für Elemente erstellen, sollten wir BindableProperty
verwenden. Mit bindbaren Eigenschaften können wir die Datenbindung auf den Seiten verwenden, die das neue Element verwenden. Der wichtigere Vorteil der bindbaren Eigenschaften ist jedoch, dass der Renderer immer dann benachrichtigt wird, wenn ein Wert geändert wird:
public class SketchView : View
{
public static readonly BindableProperty MultiTouchEnabledProperty = BindableProperty.Create("MultiTouchEnabled", typeof(bool), typeof(SketchView), false);
public bool MultiTouchEnabled
{
get => GetValue(MultiTouchEnabledProperty);
set => SetValue(MultiTouchEnabledProperty, value);
}
}
Erstellen von Renderern für ein benutzerdefiniertes Element
Wir leiten von der ViewRenderer<TView, TNativeView>
-Basisklasse ab, um Renderer für ein neues Element zu erstellen. Die Typparameter werden auf das neue Xamarin.Forms-Element (TView
) festgelegt und das native Steuerelement (TNativeView
) entsprechend.
Angenommen, wir haben ein Android-Steuerelement mit dem Namen AndroidPaintView
, dann würde die Klassendeklaration des Android-Renderers für SketchView
wie folgt aussehen:
public class SketchViewRenderer : ViewRenderer<SketchView, AndroidPaintView>
{
...
}
Erstellen des nativen Objekts in OnElementChanged
In der OnElementChanged
-Methode müssen wir das native Steuerelement erstellen. Dies unterscheidet sich etwas von dem Anpassungsworkflow, wo wir uns darauf verlassen konnten, dass es von der Basisklasse erstellt wird. Wir instanziieren zunächst das native Objekt. Dann rufen wir SetNativeControl
auf, wodurch die Control
-Eigenschaft des Renderers gefüllt wird.
OnElementChanged
könnte mehrmals von der Plattform aufgerufen werden, aber der Renderer sollte Steuerelemente OnElementChanged
mehrmals instanziieren, weshalb wir eine Wächterklausel für diesen Teil des Codes verwenden, um zu überprüfen, ob Control
bereits festgelegt ist:
protected override void OnElementChanged(...)
{
...
if (Control == null) // Create native control only if it hasn't been done before
{
SetNativeControl(new AndroidPaintView());
}
}
Der Renderer hat über die Element
-Eigenschaft automatisch Zugriff auf das Xamarin.Forms-Element. Nachdem wir SetNativeControl
aufgerufen haben, hat er auch über die Control
-Eigenschaft Zugriff auf das native Steuerelement.
Verarbeiten von Änderungen in bindbaren Eigenschaften
Wenn wir unsere Elemente mit bindbaren Eigenschaften entwickelt haben, muss unser Renderer in der Lage sein, vom App-Code vorgenommene Änderungen an diesen Eigenschaften zu verarbeiten. Wir können diese Änderungen durch Überschreiben der OnElementPropertyChanged
-Methode verarbeiten. Das Überschreiben wird immer dann aufgerufen, wenn eine BindableProperty
im Element
geändert wird. Da es für alle bindbaren Eigenschaften aufgerufen wird, müssen wir den überprüfen und benutzerdefinierte Logik für jede Eigenschaft verwenden, die der Renderer verarbeitet. Unsere Logik tut alles, was erforderlich ist, um den Wert zu konvertieren und in das native Objekt zu kopieren:
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == SketchView.InkColorProperty.PropertyName)
{
Control.SetInkColor(Element.InkColor.ToAndroid());
}
}