{"id":19349,"date":"2015-06-22T12:24:32","date_gmt":"2015-06-22T16:24:32","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=19349"},"modified":"2015-06-22T12:24:32","modified_gmt":"2015-06-22T16:24:32","slug":"extending-xamarin-forms-controls-with-custom-renderers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/extending-xamarin-forms-controls-with-custom-renderers\/","title":{"rendered":"Extending Xamarin.Forms Controls with Custom Renderers"},"content":{"rendered":"<p>\t\t\t\tXamarin.Forms allows you to build native UIs from a single, shared codebase with over 40 pages, layouts, and mix-and-match controls. One of the most powerful aspects of Xamarin.Forms is that you not only have access to the controls that we surface, but you have 100% access to all of the native APIs on each platform as well.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-19350\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/Artboard-1-1024x948.png\" alt=\"Moments Sign Up Page\" width=\"450\" height=\"417\" \/><\/p>\n<p><b>Accessing Native APIs in Shared Code<\/b><\/p>\n<p>Accessing native APIs using Xamarin.Forms is done in one of three ways: the dependency service, custom renderers or through <a href=\"http:\/\/github.com\/xamarin\/plugins\" target=\"_blank\">plugins for Xamarin<\/a>. The <a href=\"https:\/\/developer.xamarin.com\/guides\/cross-platform\/xamarin-forms\/dependency-service\/\" target=\"_blank\">dependency service<\/a> in Xamarin.Forms allows shared code to easily resolve interfaces to platform-specific implementations, so you can easily access platform-specific features like text-to-speech, geo-location, and battery information from your PCL or Shared Project.<\/p>\n<p>User interfaces built with Xamarin.Forms look and feel native because they are native \u2014 they&#8217;re rendered using the native controls for each platform. For example, if you use an <a href=\"http:\/\/iosapi.xamarin.com\/?link=T%3aXamarin.Forms.Entry\" target=\"_blank\">Entry<\/a> control in Xamarin.Forms, on iOS this will be rendered as a UITextField, on Android as an EditText, and on Windows Phone as a TextBox. Developers can easily tap into these native renderings of Xamarin.Forms controls by using <a href=\"https:\/\/developer.xamarin.com\/guides\/cross-platform\/xamarin-forms\/custom-renderer\/\" target=\"_blank\">custom renderers<\/a>, which can be used to do everything from small tweaks of the existing control or building entire pages.<\/p>\n<p><b>Implementing a Custom Renderer<\/b><\/p>\n<p>In Moments, <a href=\"\/build-your-own-snapchat-clone-with-xamarin.forms-and-azure\/\" target=\"_blank\">a Snapchat clone built with Xamarin.Forms and Microsoft Azure<\/a>, I made extensive use of the built-in Xamarin.Forms controls. However, there were a few places I wanted a finer level of customization. Let&#8217;s look at how easy it is to tweak the Entry control&#8217;s placeholder font and color using custom renderers in the sign up page featured above. Each custom renderer has two main parts: a subclass of the control being extended and platform-specific implementations that are used to customize a control&#8217;s appearance.<\/p>\n<p><b>Subclassing Existing Controls<\/b><\/p>\n<p>In the Shared Project or PCL where your Xamarin.Forms user interface logic resides, create a subclass of the control that you wish to extend, as seen below:<\/p>\n<pre class=\"lang:csharp decode:true\">\npublic class MomentsEntry : Entry\n{\n    public MomentsEntry ()\n    {\n        TextColor = Color.White;\n    }\n}\n<\/pre>\n<p><b>Platform-Specific Implementation<\/b>\nTo customize the control&#8217;s appearance, we must create custom renderers on each platform for which we wish to customize the given control. Each Xamarin.Forms control has a renderer class that can be subclassed on each platform, such as EntryRenderer.<\/p>\n<pre class=\"lang:csharp decode:true\">\npublic class MomentsEntryRenderer : EntryRenderer\n{\n}\n<\/pre>\n<p>Next, override the OnElementChanged method. This method is where all the customization for the control takes place. All customization is done using the Control property, which is just an instance of the native mapping for the particular renderer subclassed. For example, on iOS, this would be a UITextField and on Android an EditText. Altering the placeholder color and font was as easy as altering a few properties, as seen below in both the iOS and Android implementations:<\/p>\n<h3>iOS<\/h3>\n<pre class=\"lang:csharp decode:true\">\npublic class MomentsEntryRenderer : EntryRenderer\n{\n    protected override void OnElementChanged (ElementChangedEventArgs&lt;Entry&gt; e)\n    {\n        base.OnElementChanged (e);\n\n        if (Control != null)\n        {\n            Control.BackgroundColor = UIColor.FromRGB (119, 171, 233);\n            Control.BorderStyle = UITextBorderStyle.None;\n            Control.Font = UIFont.FromName (&quot;HelveticaNeue-Thin&quot;, 20);\n            Control.SetValueForKeyPath (UIColor.White, new NSString (&quot;_placeholderLabel.textColor&quot;));\n            Control.Layer.SublayerTransform = CATransform3D.MakeTranslation (10, 0, 0);\n        }\n    }\n}\n<\/pre>\n<h3>Android<\/h3>\n<pre class=\"lang:csharp decode:true\">\npublic class MomentsEntry : EntryRenderer\n{\n    protected override void OnElementChanged (ElementChangedEventArgs&lt;Entry&gt; e)\n    {\n\t    base.OnElementChanged (e);\n\n\t    if (Control != null)\n        {\n\t        Control.SetHintTextColor (ColorStateList.ValueOf  (global::Android.Graphics.Color.White));\n\t        Control.SetBackgroundDrawable (null);\n        }\n    }\n}\n<\/pre>\n<p>Finally, to enable Xamarin.Forms to properly find and render your custom control, you must add the [assembly] attribute above the class. The first parameter references the Xamarin.Forms control you wish to alter the renderer for, while the second parameter references the platform-specific renderer for the custom control:<\/p>\n<pre class=\"lang:csharp decode:true\">\n[assembly: ExportRenderer (typeof (Moments.MomentsEntry), typeof (Moments.iOS.MomentsEntryRenderer))]<\/pre>\n<h4>The Results<\/h4>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-19350\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/beforeAndAfter.png\" alt=\"Before and after custom renderer\" width=\"450\" height=\"417\" \/><\/p>\n<p><b>Wrapping It All Up<\/b><\/p>\n<p>Custom renderers in Xamarin.Forms make it easy to extend existing Xamarin.Forms controls, <a href=\"\/using-custom-controls-in-xamarin.forms-on-android\/\" target=\"_blank\">create your own controls<\/a>, or even build entire pages using native APIs. To get started, be sure to check out the <a href=\"https:\/\/developer.xamarin.com\/guides\/cross-platform\/xamarin-forms\/custom-renderer\/\" target=\"_blank\">docs<\/a> or <a href=\"https:\/\/developer.xamarin.com\/videos\/cross-platform\/xamarinforms-custom-renderers\/\" target=\"_blank\">watch this video<\/a> from Xamarin&#8217;s Mark Smith, and you&#8217;ll be up and running with custom renderers in no time!\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Xamarin.Forms allows you to build native UIs from a single, shared codebase with over 40 pages, layouts, and mix-and-match controls. One of the most powerful aspects of Xamarin.Forms is that you not only have access to the controls that we surface, but you have 100% access to all of the native APIs on each platform [&hellip;]<\/p>\n","protected":false},"author":546,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4,16],"class_list":["post-19349","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-platform","tag-xamarin-forms"],"acf":[],"blog_post_summary":"<p>Xamarin.Forms allows you to build native UIs from a single, shared codebase with over 40 pages, layouts, and mix-and-match controls. One of the most powerful aspects of Xamarin.Forms is that you not only have access to the controls that we surface, but you have 100% access to all of the native APIs on each platform [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/19349","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/546"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=19349"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/19349\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=19349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=19349"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=19349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}