{"id":25292,"date":"2016-04-12T10:57:33","date_gmt":"2016-04-12T17:57:33","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=25292"},"modified":"2020-09-08T09:34:04","modified_gmt":"2020-09-08T16:34:04","slug":"customizing-xamarin-forms-controls-with-effects","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/customizing-xamarin-forms-controls-with-effects\/","title":{"rendered":"Customizing Xamarin.Forms Controls with Effects"},"content":{"rendered":"<pre><code>            Xamarin.Forms allows you to build native user interfaces for iOS, Android, and Windows from a single shared codebase using C# or XAML. Each user interface element in Xamarin.Forms is rendered natively on each platform using a renderer class that creates the corresponding native control for that platform. For example, the Xamarin.Forms control &lt;code&gt;Entry&lt;\/code&gt; is rendered as a &lt;code&gt;UITextField&lt;\/code&gt; on iOS, an &lt;code&gt;EditText&lt;\/code&gt; on Android, and a &lt;code&gt;TextBox&lt;\/code&gt; on Windows. By extending the existing renderer for a control, you can easily customize the appearance or behavior of a control. You can even create entirely new controls by defining a shared interface in Xamarin.Forms and create custom renderers to render the control on each platform natively. This approach is perfect for heavy platform-specific customizations.\n<\/code><\/pre>\n<p>What if you would like to perform a simple control customization? Creating a custom renderer sometimes can be a heavyweight response. Xamarin.Forms 2.1 introduces a new feature named <em>effects<\/em> that greatly simplifies this process, allowing native controls on each platform to be more easily customized. In this blog post, you will learn how to create your own custom effect for the <code>Slider<\/code> control in Xamarin.Forms.<\/p>\n<h2>Introduction to Effects<\/h2>\n<p>Effects allow the native controls on each platform to be customized without having to implement a custom renderer. They simplify the customization of a native control and are typically used for small styling changes. Anything that can be achieved with an effect can also be achieved with a custom renderer. However, custom renderers offer more flexibility and customizations. Refer to our <a href=\"https:\/\/developer.xamarin.com\/guides\/xamarin-forms\/effects\/introduction\/#Why_Use_an_Effect_over_a_Custom_Renderer\">guidelines on which approach is right<\/a> for your customization.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-25294\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Effects.png\" alt=\"Showing off Xamarin.Forms 2.1's new feature named effects with the Slider control.\" width=\"683\" height=\"384\" \/><\/p>\n<h2>Getting Started<\/h2>\n<p>Effects are written in platform-specific projects and are consumed in shared or PCL projects in Xamarin.Forms. Creating an effect involves two simple steps:<\/p>\n<ol>\n<li>Create an effect by subclassing <code>PlatformEffect<\/code> in the native platform you wish to customize.<\/li>\n<li>Consume the effect by attaching it to the appropriate Xamarin.Forms control.<\/li>\n<\/ol>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-25296\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Effects-Diagram.png\" alt=\"Diagram explaining how effects work in relation to each platform and Xamarin.Forms.\" width=\"739.5\" height=\"222\" \/><\/p>\n<h2>Creating an Effect<\/h2>\n<p>Effects are created in the platform-specific project. First, create a custom class that inherits from <code>PlatformEffect<\/code> and override the <code>OnAttached<\/code> and <code>OnDetached<\/code> methods.<\/p>\n<ul>\n<li><code>OnAttached<\/code>: called when an effect is attached to a Xamarin.Forms control. Use this method to perform customization of the control, along with exception handling in case the effect cannot be applied to the specified Xamarin.Forms control.<\/li>\n<li><code>OnDetached<\/code>: called when an effect is detached from a Xamarin.Forms control. Use this method to perform any effect cleanup, such as resetting to an older value or de-registering an event handler.<\/li>\n<\/ul>\n<h3>Applying the Customization for iOS<\/h3>\n<p>Subclass the <code>PlatformEffect<\/code> class and override the <code>OnAttached<\/code> method.<\/p>\n<pre class=\"lang:csharp decode:true\">public class RedSliderEffect : PlatformEffect\n{\n    protected override void OnAttached()\n    {\n        var slider = (UISlider)Control;\n        slider.ThumbTintColor = UIColor.FromRGB(255, 0, 0);\n        slider.MinimumTrackTintColor = UIColor.FromRGB(255, 120, 120);\n        slider.MaximumTrackTintColor = UIColor.FromRGB(255, 14, 14);\n    }\n\n    protected override void OnDetached()\n    {\n        \/\/ Use this method if you wish to reset the control to original state\n    }\n}\n<\/pre>\n<h3>Applying the Customization for Android<\/h3>\n<p>Subclass the <code>PlatformEffect<\/code> class in your Android project and write the customizations in the <code>OnAttached<\/code> method.<\/p>\n<pre class=\"lang:csharp decode:true\">public class RedSliderEffect : PlatformEffect\n{\n    protected override void OnAttached()\n    {\n        var seekBar = (SeekBar)Control;\n        seekBar.ProgressDrawable.SetColorFilter(new PorterDuffColorFilter(Xamarin.Forms.Color.Red.ToAndroid(), PorterDuff.Mode.SrcIn));\n        seekBar.Thumb.SetColorFilter(new PorterDuffColorFilter(Xamarin.Forms.Color.Red.ToAndroid(), PorterDuff.Mode.SrcIn));\n    }\n\n    protected override void OnDetached()\n    {\n        \/\/ Use this method if you wish to reset the control to original state\n    }\n}\n<\/pre>\n<h3>Setup Attributes<\/h3>\n<p>For Xamarin.Forms to discover the effects created in the platform-specific projects, we need to add <code>ResolutionGroupName<\/code> and <code>ExportEffect<\/code> attributes.<\/p>\n<ul>\n<li>Add a <code>ResolutionGroupName<\/code> attribute to the custom effect class. This attribute ensures the effects are created inside a unique namespace preventing collisions with other effects with the same name. Please note, <strong>this attribute can be applied only once per project<\/strong>. In the sample project you will see them specified only once in the <code>RedSliderEffect<\/code><code> class.<\/code><\/li>\n<li>Add an <code>ExportEffect<\/code> attribute to the custom effect class. This attribute registers the effect with a unique ID that&#8217;s used by Xamarin.Forms, along with the group name, to locate the effect prior to applying it to a control. The attribute takes two parameters: the type name of the effect and a unique string that will be used to locate the effect prior to applying it to a control.<\/li>\n<\/ul>\n<pre class=\"lang:csharp decode:true\">[assembly: ResolutionGroupName(\"EffectsSample\")]\n[assembly: ExportEffect(typeof(RedSliderEffect), \"RedSliderEffect\")]\nnamespace Effects\n{\n    ...\n}\n<\/pre>\n<h3>Consume the Effect in Xamarin.Forms<\/h3>\n<p>Effects are consumed by first defining the control in Xamarin.Forms and then adding the custom effect to its <em>Effects Collection<\/em>.<\/p>\n<pre class=\"lang:csharp decode:true\">var redSlider = new Slider\n{\n    Minimum = 0,\n    Maximum = 100,\n    Value = 80\n};\n\nvar content = new ContentPage\n{\n    Title = \"Effects\",\n    Content = new StackLayout\n    {\n        VerticalOptions = LayoutOptions.Start,\n        Children = {\n            redSlider\n        }\n    }\n};\n\nredSlider.Effects.Add(Effect.Resolve(\"EffectsSample.RedSliderEffect\"));\n<\/pre>\n<p>The <code>RedSliderEffect<\/code> is attached to the <code>Slider<\/code> instance by adding the effect to the control\u2019s Effects Collection. The <code>Effect.Resolve<\/code> method returns an effect for the specified name, which is a concatenation of the values specified in the <code>ResolutionGroupName<\/code> and the <code>ExportEffect<\/code> attributes on the effect class.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-25303\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Xamarin.Forms-Effects-Android.png\" alt=\"Xamarin.Forms-Effects-Android\" width=\"350\" height=\"325\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Wrapping Up<\/h2>\n<p>Effects are a useful feature since they allow the native controls on each platform to be customized without having to implement a custom renderer for simple and small styling changes. Effects can be further empowered for reusability by using parameters. For more information, visit our documentation on <a href=\"https:\/\/developer.xamarin.com\/guides\/xamarin-forms\/effects\/passing-parameters\/\">passing parameters to an effect<\/a>. For a hands-on look at effects, be sure to <a href=\"https:\/\/github.com\/nishanil\/Xamarin.Forms-Samples\/tree\/master\/Effects\">download the slider sample<\/a> used in this blog post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Xamarin.Forms allows you to build native user interfaces for iOS, Android, and Windows from a single shared codebase using C# or XAML. Each user interface element in Xamarin.Forms is rendered natively on each platform using a renderer class that creates the corresponding native control for that platform. For example, the Xamarin.Forms control &lt;code&gt;Entry&lt;\/code&gt; is rendered [&hellip;]<\/p>\n","protected":false},"author":593,"featured_media":25294,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4,16],"class_list":["post-25292","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 user interfaces for iOS, Android, and Windows from a single shared codebase using C# or XAML. Each user interface element in Xamarin.Forms is rendered natively on each platform using a renderer class that creates the corresponding native control for that platform. For example, the Xamarin.Forms control &lt;code&gt;Entry&lt;\/code&gt; is rendered [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/25292","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\/593"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=25292"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/25292\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=25292"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=25292"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=25292"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}