{"id":34664,"date":"2017-12-08T12:37:58","date_gmt":"2017-12-08T20:37:58","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=34664"},"modified":"2017-12-08T12:37:58","modified_gmt":"2017-12-08T20:37:58","slug":"native-forms-polished-shiny-xamarin-forms-2-5-0","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/native-forms-polished-shiny-xamarin-forms-2-5-0\/","title":{"rendered":"Native Forms is Polished and Shiny in Xamarin.Forms 2.5.0"},"content":{"rendered":"<p>\t\t\t\tSince we <a href=\"https:\/\/blog.xamarin.com\/unleashed-embedding-xamarin-forms-in-xamarin-native\/\">previewed Native Forms<\/a> in June, we\u2019ve been working to smooth the rough edges and polish it up for Xamarin.Forms 2.5.0 by fixing bugs and integrating the excellent feedback from the community.<\/p>\n<p>Last month at Microsoft Connect(); in New York, several Native Forms examples were used in the keynote presentation. Most notably, James Montemagno demonstrated adding a Xamarin.Forms page to the open source Kickstarter iOS application. You can <a href=\"https:\/\/channel9.msdn.com\/Events\/Connect\/2017\/K100\" target=\"_blank\" rel=\"noopener noreferrer\">watch the entire keynote on Channel9<\/a>.<\/p>\n<p><img decoding=\"async\" class=\"alignright size-full wp-image-34666\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/2017-12-07_20-01-00.gif\" alt=\"\" width=\"217\" height=\"426\" \/><\/p>\n<p>Another example is the SmartHotel360 suite of applications, which includes a maintenance application that uses Native Forms to composite Xamarin.Forms pages into native Xamarin.iOS and Xamarin.Android applications. The full code for these applications will be made available soon on GitHub.\n&lt;!&#8211;\n<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-12-07-20.20.36.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-12-07-20.20.36.png\" alt=\"\" width=\"1090\" height=\"1928\" class=\"alignright size-full wp-image-34668\" \/><\/a>\n&#8211;&gt;<\/p>\n<p>This post covers these changes and serves as a guide for you to get started embedding Native Forms in your own applications.<\/p>\n<h2>What is Native Forms?<\/h2>\n<p>The <strong>tl;dr;<\/strong> is that Native Forms allows you to use a Xamarin.Forms ContentPage in a native Xamarin.iOS, Xamarin.Android, or UWP application.<\/p>\n<p>But why, you may ask, would I want to do that? Let&#8217;s consider some scenarios:<\/p>\n<p><strong>Existing Xamarin.Forms Reuse<\/strong><\/p>\n<p>Perhaps you wrote a login page for a service in a previous Xamarin.Forms project. Now, you&#8217;re working on a native Xamarin project which uses the same service. Rather than write that page again, you can simply reuse it directly from the Forms project.<\/p>\n<p><strong>Migrate Xamarin.Forms to Xamarin Native<\/strong><\/p>\n<p>Let&#8217;s say you used Xamarin.Forms to quickly create a prototype or proof-of-concept application. For version two, you have decided that on iOS you need to go native. However, you&#8217;re not thrilled with the prospect of rewriting every single page from the prototype for your native app. With Native Forms, you can reuse pages from the prototype and only rewrite what you absolutely have to.<\/p>\n<p><strong>Mix Xamarin.Forms into Xamarin Native Projects<\/strong><\/p>\n<p>You\u2019re working on multiple native projects and facing the prospect of writing the same \u201cSettings\u201d and \u201cAbout\u201d pages three times. Stop! Just write them once in a Xamarin.Forms project and embed them in your native apps!<\/p>\n<h2>A Simple Scenario<\/h2>\n<p>To show Native Forms in action, let\u2019s walk through a scenario with some code. <a href=\"https:\/\/github.com\/hartez\/FormsEmbeddingPreview\">The full code for this example can be found on GitHub<\/a>.<\/p>\n<p>Let\u2019s say I\u2019m creating brand new native applications for UWP, Android, and iOS. In each one, I\u2019d like to add a tip calculator, but I really don\u2019t want to write three tip calculators from scratch. Luckily for me, <a href=\"https:\/\/github.com\/xamarin\/xamarin-forms-samples\/tree\/master\/TipCalc\">Charles Petzold has already written one in Xamarin.Forms<\/a>, so all I have to do is embed it in each of the native apps.<\/p>\n<p>In the demo solution, I\u2019ve created three native projects, plus a project for the TipCalc code:<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/hartez\/FormsEmbeddingPreview\/master\/images\/solution.png\" alt=\"Solution\" \/><figcaption>Solution<\/figcaption><\/figure>\n<p>In my TipCalc project, I\u2019ve simply copy-pasted the code from the original TipCalc solution\u2019s PCL project. The code works as-is without any changes, but in my project I\u2019ve updated some obsolete XAML and added some <code>MessagingCenter<\/code> code, which I\u2019ll talk about later.<\/p>\n<p>To embed the code in each native application, I need to add a reference to the TipCalc project and install the Xamarin.Forms NuGet package. Once I\u2019ve done that, my references in each native project will look something like this:<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/hartez\/FormsEmbeddingPreview\/master\/images\/refs.png\" alt=\"iOS project references\" \/><figcaption>iOS project references<\/figcaption><\/figure>\n<p>Before each native project can embed any Xamarin.Forms pages, they need to initialize Forms by calling <code>Forms.Init()<\/code>. <em>When<\/em> a native application does this is up to you, as long as it happens before constructing any instance of a Forms <code>ContentPage<\/code>. You may choose to do it at startup (e.g., during <code>UIApplicationDelegate.FinishedLaunching()<\/code> or <code>Activity.OnCreate()<\/code>), or you may want to wait until right before the first <code>ContentPage<\/code> is constructed. The right option for you will depend primarily on when it\u2019s most convenient in your application flow.<\/p>\n<p>After Xamarin.Forms is initialized, it\u2019s just a matter of setting up navigation to the <code>TipCalcPage<\/code>. Native Forms adds some extension methods to Xamarin.Forms, which handle converting a <code>ContentPage<\/code> to the appropriate native type.<\/p>\n<p>In a native iOS project, for example, you would normally use <code>UINavigationController.PushViewController()<\/code> with a <code>UIViewController<\/code>. Native Forms provides an extension to <code>ContentPage<\/code>, which converts the page to a <code>UIViewContoller<\/code> for you. The method for navigating to the tip calculator could be as simple as:<\/p>\n<pre><code>public void NavigateToTipCalc()\n{\n    _navigation.PushViewController(new TipCalcPage().CreateViewController(), true);\n}<\/code><\/pre>\n<p>where <code>_navigation<\/code> is a <code>UINavigationController<\/code>. That\u2019s it; call that method from the \u201cTip Calculator\u201d button and the application navigates to the Xamarin.Forms page.<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/hartez\/FormsEmbeddingPreview\/master\/images\/ios.gif\" alt=\"Navigating to the embedded Forms page on iOS\" \/><figcaption>Navigating to the embedded Forms page on iOS<\/figcaption><\/figure>\n<p>On Android, Native Forms provides the <code>CreateFragment()<\/code> and <code>CreateSupportFragment()<\/code> methods. These will convert a <code>ContentPage<\/code> into a <code>Fragment<\/code> suitable for navigation. For example, add a method like this to a <code>FragmentActivity<\/code>:<\/p>\n<pre><code>public void NavigateToTipCalc()\n{\n    var ft = SupportFragmentManager.BeginTransaction();\n\n    ft.AddToBackStack(null);\n    ft.Replace(Resource.Id.fragment_frame_layout,\n        new TipCalcPage().CreateSupportFragment(this), \"TipCalc\");\n\n    ft.Commit();\n}<\/code><\/pre>\n<figure><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/hartez\/FormsEmbeddingPreview\/master\/images\/android.gif\" alt=\"Navigating to the embedded Forms page on Android\" \/><figcaption>Navigating to the embedded Forms page on Android<\/figcaption><\/figure>\n<p>For native UWP applications, navigation is typically done with the <code>Frame<\/code> class; the <code>Frame.Navigate()<\/code> method takes a <code>Page<\/code> type and navigates to an instance of it. Native Forms provides a similar extension to <code>Frame<\/code>, which takes a <code>ContentPage<\/code> instance. Navigating can be as simple as:<\/p>\n<pre><code>private void NavigateToTipCalc()\n{\n    Frame.Navigate(new TipCalcPage());\n}<\/code><\/pre>\n<figure><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/hartez\/FormsEmbeddingPreview\/master\/images\/uwp.gif\" alt=\"Navigating to the embedded Forms page on UWP\" \/><figcaption>Navigating to the embedded Forms page on UWP<\/figcaption><\/figure>\n<p>As you can see, using Native Forms doesn\u2019t take a whole lot of code.<\/p>\n<h2>Handling Communication<\/h2>\n<p>Chances are good that you also need to communicate between the native context and the Xamarin.Forms portions of your apps. If you\u2019re reusing Xamarin.Forms code from another project, you may already have something set up using whatever event aggregator, message bus, or other method makes sense for your stack. But if you don\u2019t already have something in place, Xamarin.Forms comes with a built-in messaging service (called <code>MessagingCenter<\/code>) which can be used to wire up communications between native applications and the Xamarin.Forms pages they host.<\/p>\n<p>In this demo solution, I\u2019ve modified the TipCalc project a bit to allow it to send and receive data to and from its host app using <code>MessagingCenter<\/code>. I\u2019ve defined messages and their arguments:<\/p>\n<pre><code>public static class Messages {\n    public static object Sender = new object();\n    public const string InitialAmount = \"InitialAmount\";\n    public const string Tip = \"Tip\";\n}\n\npublic class InitialAmountArgs {\n    public InitialAmountArgs(double initialAmount) {\n        InitialAmount = initialAmount;\n    }\n\n    public double InitialAmount { get; }\n}\n\npublic class TipArgs {\n    public TipArgs(double tip) {\n        Tip = tip;\n    }\n\n    public double Tip { get; }\n}<\/code><\/pre>\n<p>With that infrastructure in place, it\u2019s easy for the native applications to specify an initial amount for the tip calculator. Each native app has a field for entering the initial amount; when the user updates that field, a message is sent:<\/p>\n<pre><code>MessagingCenter.Send(TipCalc.Messages.Sender, TipCalc.Messages.InitialAmount, \n    new InitialAmountArgs(InitialAmount));<\/code><\/pre>\n<p>The view model in the TipCalc project (<code>TipCalcModel<\/code>) listens for that message and reacts accordingly:<\/p>\n<pre><code>MessagingCenter.Subscribe(this, Messages.InitialAmount, (s, e) =&gt;\n{\n    SubTotal = e.InitialAmount;\n});<\/code><\/pre>\n<p>It\u2019s also simple for the native apps to respond to changes in the calculated tip value. Whenever the <code>TipAmount<\/code> in <code>TipCalcModel<\/code> changes, it sends a message:<\/p>\n<pre><code>MessagingCenter.Send(Messages.Sender, Messages.Tip, new TipArgs(value));<\/code><\/pre>\n<p>The native application can listen for that message and react; for example, the iOS application sets the text of a UILabel:<\/p>\n<pre><code>MessagingCenter.Subscribe(TipCalc.Messages.Sender, TipCalc.Messages.Tip,\n    (obj, args) =&gt; TipAmount.Text = args.Tip.ToString(\"C\"));<\/code><\/pre>\n<p>Here\u2019s the app in action on UWP. The user enters an initial amount, which is passed to the tip calculator, and the result from the tip calculator is relayed back to the native page:<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/hartez\/FormsEmbeddingPreview\/master\/images\/uwp_communication.gif\" alt=\"Communication on UWP\" \/><figcaption>Communication on UWP<\/figcaption><\/figure>\n<h2>Just Pages?<\/h2>\n<p>Savvy readers will have noticed that the extension methods all provide return types that don\u2019t necessarily <em>require<\/em> full page navigation. It&#8217;s also possible to use <code>UIViewController<\/code>, <code>FrameworkElement<\/code>, and <code>Fragment<\/code> as <em>part<\/em> of a page rather than a full screen. <a href=\"https:\/\/github.com\/davidortinau\/build2017-new-in-xamarin-forms#uwp-desktop\">We previously showed<\/a> how to display a <code>ContentPage<\/code> on UWP inside of a <code>Flyout<\/code>, instead of a full page.<\/p>\n<p>In theory, these methods could be used to embed a <code>ContentPage<\/code> as part of a larger page on each platform. As of right now, that&#8217;s very much an <em>officially <strong>un<\/strong>supported<\/em> use case. That said, if you experiment with that use case, I\u2019d love to hear how it works for you.<\/p>\n<h2>Update to 2.5.0 Today!<\/h2>\n<p>You can begin using Native Forms today in our latest stable version, Xamarin.Forms 2.5.0, available on NuGet. If you have any feedback or suggestions, please let us know <a href=\"https:\/\/forums.xamarin.com\/96889\/preview-xamarin-forms-embedding\/p1\">in the forums<\/a>!\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since we previewed Native Forms in June, we\u2019ve been working to smooth the rough edges and polish it up for Xamarin.Forms 2.5.0 by fixing bugs and integrating the excellent feedback from the community. Last month at Microsoft Connect(); in New York, several Native Forms examples were used in the keynote presentation. Most notably, James Montemagno [&hellip;]<\/p>\n","protected":false},"author":1962,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[16],"class_list":["post-34664","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-forms"],"acf":[],"blog_post_summary":"<p>Since we previewed Native Forms in June, we\u2019ve been working to smooth the rough edges and polish it up for Xamarin.Forms 2.5.0 by fixing bugs and integrating the excellent feedback from the community. Last month at Microsoft Connect(); in New York, several Native Forms examples were used in the keynote presentation. Most notably, James Montemagno [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/34664","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\/1962"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=34664"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/34664\/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=34664"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=34664"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=34664"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}