Xamarin.Forms
Aangepaste besturingselementen maken
Zoeken…
Invoering
Elke Xamarin.Forms weergave heeft een bijbehorende renderer voor elk platform dat een instantie van een native besturingselement maakt. Wanneer een weergave wordt weergegeven op het specifieke platform, wordt de ViewRenderer klasse geïnstantieerd.
Het proces hiervoor is als volgt:
Maak een Xamarin.Forms aangepast besturingselement.
Gebruik de aangepaste besturing van Xamarin.Forms.
Maak de aangepaste renderer voor de besturing op elk platform.
Een CheckBox-besturingselement implementeren
In dit voorbeeld implementeren we een aangepaste checkbox voor Android en iOS.
Aangepast besturingselement maken
namespace CheckBoxCustomRendererExample
{
public class Checkbox : View
{
public static readonly BindableProperty IsCheckedProperty = BindableProperty.Create<Checkbox, bool>(p => p.IsChecked, true, propertyChanged: (s, o, n) => { (s as Checkbox).OnChecked(new EventArgs()); });
public static readonly BindableProperty ColorProperty = BindableProperty.Create<Checkbox, Color>(p => p.Color, Color.Default);
public bool IsChecked
{
get
{
return (bool)GetValue(IsCheckedProperty);
}
set
{
SetValue(IsCheckedProperty, value);
}
}
public Color Color
{
get
{
return (Color)GetValue(ColorProperty);
}
set
{
SetValue(ColorProperty, value);
}
}
public event EventHandler Checked;
protected virtual void OnChecked(EventArgs e)
{
if (Checked != null)
Checked(this, e);
}
}
}
We beginnen met de Android Custom Renderer door een nieuwe klasse ( CheckboxCustomRenderer ) te maken in het Android gedeelte van onze oplossing.
Een paar belangrijke details om op te merken:
- We moeten de top van onze klasse markeren met het kenmerk ExportRenderer zodat de renderer wordt geregistreerd bij
Xamarin.Forms. Op deze manier zalXamarin.Formsdeze renderer gebruiken wanneer het probeert onsCheckboxobject opAndroid. - We doen het grootste deel van ons werk in de
OnElementChangedmethode, waarbij we onze eigen besturing instantiëren en instellen.
De aangepaste bediening gebruiken
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:CheckBoxCustomRendererExample" x:Class="CheckBoxCustomRendererExample.CheckBoxCustomRendererExamplePage">
<StackLayout Padding="20">
<local:Checkbox Color="Aqua" />
</StackLayout>
</ContentPage>
De aangepaste renderer maken op elk platform
Het proces voor het maken van de aangepaste rendererklasse is als volgt:
- Maak een subklasse van de
ViewRenderer<T1,T2>die het aangepaste besturingselementViewRenderer<T1,T2>. Het eerste type argument moet het aangepaste besturingselement zijn waarvoor de renderer is bedoeld, in dit gevalCheckBox. Het tweede type argument moet het native besturingselement zijn dat het aangepaste besturingselement implementeert. - Overschrijf de
OnElementChangedmethode die de aangepaste besturing enOnElementChangedom deze aan te passen. Deze methode wordt aangeroepen wanneer het bijbehorendeXamarin.Formsbesturingselement wordt gemaakt. - Voeg een
ExportRendererkenmerk toe aan de aangepaste rendererklasse om op te geven dat dit wordt gebruikt om het aangepaste besturingselementXamarin.Formste renderen. Dit kenmerk wordt gebruikt om de aangepaste renderer te registreren bijXamarin.Forms.
De aangepaste Renderer voor Android maken
[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.Droid
{
public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBox>
{
private CheckBox checkBox;
protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
{
base.OnElementChanged(e);
var model = e.NewElement;
checkBox = new CheckBox(Context);
checkBox.Tag = this;
CheckboxPropertyChanged(model, null);
checkBox.SetOnClickListener(new ClickListener(model));
SetNativeControl(checkBox);
}
private void CheckboxPropertyChanged(Checkbox model, String propertyName)
{
if (propertyName == null || Checkbox.IsCheckedProperty.PropertyName == propertyName)
{
checkBox.Checked = model.IsChecked;
}
if (propertyName == null || Checkbox.ColorProperty.PropertyName == propertyName)
{
int[][] states = {
new int[] { Android.Resource.Attribute.StateEnabled}, // enabled
new int[] {Android.Resource.Attribute.StateEnabled}, // disabled
new int[] {Android.Resource.Attribute.StateChecked}, // unchecked
new int[] { Android.Resource.Attribute.StatePressed} // pressed
};
var checkBoxColor = (int)model.Color.ToAndroid();
int[] colors = {
checkBoxColor,
checkBoxColor,
checkBoxColor,
checkBoxColor
};
var myList = new Android.Content.Res.ColorStateList(states, colors);
checkBox.ButtonTintList = myList;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (checkBox != null)
{
base.OnElementPropertyChanged(sender, e);
CheckboxPropertyChanged((Checkbox)sender, e.PropertyName);
}
}
public class ClickListener : Java.Lang.Object, IOnClickListener
{
private Checkbox _myCheckbox;
public ClickListener(Checkbox myCheckbox)
{
this._myCheckbox = myCheckbox;
}
public void OnClick(global::Android.Views.View v)
{
_myCheckbox.IsChecked = !_myCheckbox.IsChecked;
}
}
}
}
De aangepaste Renderer voor iOS maken
Aangezien in iOS het ingebouwde selectievakje niet is ingebouwd, maken we eerst een CheckBoxView en maken we vervolgens een renderer voor ons Xamarin.Forms-selectievakje.
De CheckBoxView is gebaseerd op twee afbeeldingen, check_checkbox.png en unchecked_checkbox.png, zodat de eigenschap Color wordt genegeerd.
De weergave CheckBox:
namespace CheckBoxCustomRendererExample.iOS
{
[Register("CheckBoxView")]
public class CheckBoxView : UIButton
{
public CheckBoxView()
{
Initialize();
}
public CheckBoxView(CGRect bounds)
: base(bounds)
{
Initialize();
}
public string CheckedTitle
{
set
{
SetTitle(value, UIControlState.Selected);
}
}
public string UncheckedTitle
{
set
{
SetTitle(value, UIControlState.Normal);
}
}
public bool Checked
{
set { Selected = value; }
get { return Selected; }
}
void Initialize()
{
ApplyStyle();
TouchUpInside += (sender, args) => Selected = !Selected;
// set default color, because type is not UIButtonType.System
SetTitleColor(UIColor.DarkTextColor, UIControlState.Normal);
SetTitleColor(UIColor.DarkTextColor, UIControlState.Selected);
}
void ApplyStyle()
{
SetImage(UIImage.FromBundle("Images/checked_checkbox.png"), UIControlState.Selected);
SetImage(UIImage.FromBundle("Images/unchecked_checkbox.png"), UIControlState.Normal);
}
}
}
De aangepaste renderer van CheckBox:
[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.iOS
{
public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBoxView>
{
/// <summary>
/// Handles the Element Changed event
/// </summary>
/// <param name="e">The e.</param>
protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
{
base.OnElementChanged(e);
if (Element == null)
return;
BackgroundColor = Element.BackgroundColor.ToUIColor();
if (e.NewElement != null)
{
if (Control == null)
{
var checkBox = new CheckBoxView(Bounds);
checkBox.TouchUpInside += (s, args) => Element.IsChecked = Control.Checked;
SetNativeControl(checkBox);
}
Control.Checked = e.NewElement.IsChecked;
}
Control.Frame = Frame;
Control.Bounds = Bounds;
}
/// <summary>
/// Handles the <see cref="E:ElementPropertyChanged" /> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName.Equals("Checked"))
{
Control.Checked = Element.IsChecked;
}
}
}
}
Resultaat:

