There are a few good examples already of how to create a "custom control" by -
I want to create a "compound custom control OR usercontrol" which contains multiple elements which are defined in XAML (in the shared code), and then customised with a renderer (to say tweak the styling per platform).
Does anyone have an example of doing this please? A simple example with a view that has a bindable label and an entry box should be enough to show the main principles.
Here is what I have so far -
Defined a ContentView to represent our usercontrols layout and contents.
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="News.Forms.VisualNewsContentView">
<ContentView.Content>
<StackLayout>
<Label x:Name="MyLabel" Text="Label"></Label>
<Entry x:Name="MyEntry" Text="Entry"></Entry>
</StackLayout>
</ContentView.Content>
</ContentView>
with codebehind -
public partial class VisualNewsContentView : ContentView
{
public VisualNewsContentView ()
{
InitializeComponent ();
}
// Not sure if I need this to access Entry ...
public Entry GetEntry ()
{
return MyEntry;
}
}
Add an Android Custom Renderer for that ContentView, how do I access and customise natively parts / controls of the ContentView?
[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]
namespace News.Forms.Android
{
public class VisualNewsRenderer: ViewRenderer
{
public VisualNewsRenderer () { }
protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged (oldModel, newModel);
if (newModel != null) {
VisualNewsContentView newsContentView = newModel as VisualNewsContentView;
// i.e. How could I get hold of EditText etc so I could natively customise its appearance? When you use a built in renderer like EntryRenderer you can use Control to access native control.
Console.WriteLine (newsContentView.GetLabel ().Text);
EditText ed = (EditText)newsContentView.GetEntry ().???
}
}
}
}
Just can't quite get the pieces together to work, the ContentView seems to render fine on page but cannot work out how to access its Child Native controls in the viewrenderer.
Be nice to also show how you can use Binding for the Label and Entry Text values.
I do not want to have to define a custom renderer for each single label / entry etc of the usercontrol.
Is this what you meant?
Some properties to access the Xamarin.Forms controls:
public partial class VisualNewsContentView : ContentView
{
public VisualNewsContentView()
{
InitializeComponent();
}
public Label Label
{
get
{
return MyLabel;
}
set
{
MyLabel = value;
}
}
public Entry Entry
{
get
{
return MyEntry;
}
set
{
MyEntry = value;
}
}
}
Some magic inside the Renderer to customize the controls on the page:
[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]
namespace News.Forms.Android
{
public class VisualNewsRenderer: ViewRenderer
{
public VisualNewsRenderer () { }
protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged (oldModel, newModel);
if (newModel != null) {
VisualNewsContentView newsContentView = newModel as VisualNewsContentView;
newsContentView.Label.Text = "It´s some kind of..";
newsContentView.Entry.Text = "MAGIC!";
newsContentView.Entry.BackgroundColor = Color.Blue;
newsContentView.Entry.RotationX = 180;
newsContentView.Entry.Focus();
}
}
}
}
EDIT:
I don't know if it's possible to map your controls from the XAML-page to native controls. You could add the controls which you want to customize natively @ the renderer.
[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]
namespace News.Forms.Android
{
public class VisualNewsRenderer: NativeRenderer
{
public VisualNewsRenderer () { }
protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged (oldModel, newModel);
if (newModel != null) {
LinearLayout layout = new LinearLayout (Application.Context);
layout.Orientation = Orientation.Vertical;
TextView tv = new TextView (Application.Context);
tv.Ellipsize = TextUtils.TruncateAt.Middle;
tv.Text = "It´s some kind of..";
EditText et = new EditText (Application.Context);
et.SetTextColor (Graphics.Color.Chocolate);
et.Text = "MAGIC!";
layout.AddView (tv);
layout.AddView (et);
SetNativeControl (layout);
}
}
}
}
But like this you won't be using your ContentView.. I'm sorry, I have nothing better than this..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With