Xamarin.Forms UserControl using XAML and Custom Renderer

There are some good examples of how to create a ā€œcustom controlā€ with

I want to create an ā€œOR usercontrol composite user controlā€ that contains several elements that are defined in XAML (in common code) and then configured using a visualization tool (to say, on the platform).

Does anyone have an example of this? A simple presentation example that has a label and an input field should be sufficient to show the basic principles.

Here is what I still have -

Defined by ContentView to represent our layout and our user’s content.

<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 Android custom rendering for this ContentView, how do I access and customize my own parts / controls for 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; // ie 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 ().??? } } } } 

It’s just not possible to put everything together, the ContentView seems to be working fine on the page, but cannot decide how to access its Child Native elements in the viewrenderer.

It is also nice to show how you can use binding for label values ​​and text input.

I do not want to define a custom renderer for each individual label / record, etc. usercontrol.

+6
source share
2 answers

Is that what you meant?

Some properties for accessing 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 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 is possible to map controls to a XAML page with my own controls. You can add the controls you want to customize initially with 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 you, you will not use your ContentView. Sorry, I have nothing better than this.

+2
source

My solution for customizing a composite user control is a custom control for each control used in a composite user control. For example, what control:

 <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> 

I will do something like this:

 <ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:CustomControls="clr-namespace:App.CustomControls;assembly=App" x:Class="News.Forms.VisualNewsContentView"> <ContentView.Content> <CustomControls:StackLayout> <CustomControls:Label x:Name="MyLabel" Text="Label"></CustomControls:Label> <CustomControls:Entry x:Name="MyEntry" Text="Entry"></CustomControls:Entry> </CustomControls:StackLayout> </ContentView.Content> </ContentView> 

Class example for CustomControls: StackLayout:

(in StackLayout.cs)

 using Xamarin.Forms; namespace App.CustomControls { public class StackLayout : Xamarin.Forms.StackLayout { } } 

(in StackLayoutRenderer.cs for android project)

 [assembly: ExportRenderer(typeof(App.CustomControls.StackLayout), typeof(App.Droid.CustomRenderers.StackLayoutRenderer))] namespace App.Droid.CustomRenderers.MapView { public class StackLayoutRenderer : ViewRenderer<StackLayout, Android.Widget.LinearLayout> { protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e) { base.OnElementChanged(e); } } } 
+1
source

Source: https://habr.com/ru/post/971912/


All Articles