{"id":2998,"date":"2016-04-22T13:49:34","date_gmt":"2016-04-22T16:49:34","guid":{"rendered":"https:\/\/www.mxcursos.com\/blog\/?p=2998"},"modified":"2019-03-16T02:56:42","modified_gmt":"2019-03-16T05:56:42","slug":"navigation-e-messaging-com-xamarin-forms-pagecontext","status":"publish","type":"post","link":"https:\/\/www.mxcursos.com\/blog\/navigation-e-messaging-com-xamarin-forms-pagecontext\/","title":{"rendered":"Navigation e Messaging com Xamarin.Forms PageContext"},"content":{"rendered":"<p>Oi pessoal do MX Cursos, hoje vamos falar de PageContext, algu\u00e9m j\u00e1 ouviu falar ? N\u00e3o? Ent\u00e3o, este foi um termo que utilizei j\u00e1 que estaremos tratando no pr\u00f3prio contexto das Pages no Xamarin.Forms e o nome parece ser bem fiel\u2026<\/p>\n<p>Em um r\u00e1pido preview apresentaremos um diagrama simples para esbo\u00e7ar um projeto cujo sua camada de apresenta\u00e7\u00e3o esteja sob o pattern MVVM ( Model-View-Viewmodel \u2013 intr\u00ednseco ao Xamarin ).<\/p>\n<p><a href=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/mvvm-300x156-1.jpg\" rel=\"attachment wp-att-2999\"><img decoding=\"async\" class=\"size-full wp-image-2999 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/mvvm-300x156-1.jpg\" alt=\"mvvm-300x156\" width=\"300\" height=\"156\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/mvvm-300x156-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/mvvm-300x156-1-24x12.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/rehansaeed.com\/tag\/windows-phone\/\" target=\"_blank\" rel=\"noopener\">http:\/\/rehansaeed.com\/tag\/windows-phone\/<\/a><\/p>\n<p><strong>View<\/strong> \u2013 Respons\u00e1vel por definir a estrutura, layout e apar\u00eancia do que os usu\u00e1rios veem na tela. As defini\u00e7\u00f5es das views podem ser feitas tanto em XAML ou Code API, com um code-behind sem l\u00f3gicas de neg\u00f3cio e defini\u00e7\u00f5es de eventos para os objetos visuais (utilizando XAML, ter\u00edamos somente a chamada do m\u00e9todo InitializeComponent e no Code API, a instancia\u00e7\u00e3o e inicializa\u00e7\u00e3o dos objetos visuais, e \u00e0 conex\u00e3o entre a View e a ViewModel atrav\u00e9s da propriedade de BindingContext, \u2026.)<\/p>\n<p><strong>\u00a0Viewmodel<\/strong> \u2013\u00a0 Atua como um interm\u00e9dio entre a view e a model, e \u00e9 respons\u00e1vel por manipular a l\u00f3gica de neg\u00f3cio. A viewmodel recupera e disponibiliza dados da model de forma que a view possa facilmente manipul\u00e1-los, esta por sua vez fornece <strong>Commands<\/strong> que um usu\u00e1rio da aplica\u00e7\u00e3o inicia na view.<\/p>\n<p><strong>\u00a0Model<\/strong> \u2013 A model no MVVM \u00e9 uma implementa\u00e7\u00e3o do dom\u00ednio da aplica\u00e7\u00e3o que incluem modelo de dados juntos com o neg\u00f3cio e l\u00f3gica de valida\u00e7\u00e3o. Exemplos de modelo de objetos incluem repositories, objetos de neg\u00f3cio, DTO (Data Transfer Objects ), POCOs (\u00a0 Plain Old CLR Objects ), entidades e objetos proxy.<\/p>\n<p>Agora com as defini\u00e7\u00f5es compreendidas, vamos fluir na constru\u00e7\u00e3o da nossa Sample Application ( Estamos utilizando o Visual Studio Community 2015 \u2013 ( Sensacional ) ).<\/p>\n<p>Crie um novo projeto em Cross-Platform selecionando o ItemTemplate Blank App ( \u00e0 escolha da abordagem Shared ou Portable fica por sua conta\u2026. ).<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3000 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/project-2-300x193-1.jpg\" alt=\"project-2-300x193\" width=\"300\" height=\"193\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/project-2-300x193-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/project-2-300x193-1-24x15.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Com o projeto gerado a nossa Solution ficar\u00e1 da seguinte forma.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-3001 size-full aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/solution-300x178-1.jpg\" alt=\"solution-300x178\" width=\"300\" height=\"178\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/solution-300x178-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/solution-300x178-1-24x14.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Fazendo um r\u00e1pido entendimento sobre o que ser\u00e1 o \u00a0helper PageContext, \u00a0sabemos que o modelo de naveg\u00e3o utilizado no Xamarin.Forms se basea na interface INavigation membro da classe VisualElement e as mensagens pop-ups ( o Xamarin.Forms as implementa nativamente em cada plataforma ) atrav\u00e9s dos m\u00e9todos DisplayAlert() e DisplayActionSheet presentes na classe Page. De certa forma poder\u00edamos utilizar estes elementos atrav\u00e9s do Code-Behind das nossas classes que representam as Pages da nossa aplica\u00e7\u00e3o, j\u00e1 que os mesmos est\u00e3o presentes nas classes ancestrais; mas, como a inten\u00e7\u00e3o \u00e9 utilizar o modelo MVVM e como dito anteriormente que as Views se conectam \u00e0s ViewModels atrav\u00e9s da propriedade BindingContext ( membro da classe BindableObject ), n\u00e3o faremos chamadas aos m\u00e9todos de navega\u00e7\u00e3o ou mensagens, pois os objetos visuais utilizar\u00e3o o mecanismo de DataBinding com Commands para designar tais a\u00e7\u00f5es. Os commands s\u00e3o membros da ViewModel, e esta por sua vez n\u00e3o possui ou n\u00e3o deve ter refer\u00eancias \u00e0s Pages ( como por exemplo manipular seus objetos visuais), assim mantemos as responsabilidades das ViewModels bem definidas. Tudo soa bastante interessante, mas vai uma pergunta, como n\u00e3o utilizaremos Code-Behind e as ViewModels por n\u00e3o conhecerem as Pages, como utilizaremos a Navega\u00e7\u00e3o ou Mensagens em nossa aplica\u00e7\u00e3o ? Neste ponto entra o PageContext, que garantir\u00e1 a independ\u00eancia entre as Views e ViewModels, utilizando Inje\u00e7\u00e3o de Depend\u00eancia para executar a navega\u00e7\u00e3o e mensagens. Como resultado final nossa aplica\u00e7\u00e3o ficar\u00e1 da seguinte forma:<\/p>\n<p style=\"text-align: center;\">Windows Phone:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-3002 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/windows-phone.fw_-180x300-1.jpg\" alt=\"windows-phone.fw_-180x300\" width=\"180\" height=\"300\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/windows-phone.fw_-180x300-1.jpg 180w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/windows-phone.fw_-180x300-1-14x24.jpg 14w\" sizes=\"(max-width: 180px) 100vw, 180px\" \/><\/p>\n<p style=\"text-align: center;\">Android:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-3003 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/android.fw_-213x300-1.jpg\" alt=\"android.fw_-213x300\" width=\"213\" height=\"300\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/android.fw_-213x300-1.jpg 213w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/android.fw_-213x300-1-17x24.jpg 17w\" sizes=\"(max-width: 213px) 100vw, 213px\" \/><\/p>\n<p style=\"text-align: center;\">iOS:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-3004 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/ios.fw_-169x300-1.jpg\" alt=\"ios.fw_-169x300\" width=\"169\" height=\"300\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/ios.fw_-169x300-1.jpg 169w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/ios.fw_-169x300-1-14x24.jpg 14w\" sizes=\"(max-width: 169px) 100vw, 169px\" \/><\/p>\n<p>Vamos utilizar em nosso exemplo o cont\u00e2iner de IoC conhecido com Autofac (<a href=\"http:\/\/autofac.org\/\" target=\"_blank\" rel=\"noopener\">http:\/\/autofac.org\/<\/a>\u00a0 ), para isto, utilize a op\u00e7\u00e3o Manage Nuget Packages, ou atrav\u00e9s do menu <em><strong>Tools <\/strong>-&gt; <strong>Nuget Package Manager<\/strong> -&gt; <strong>Package Manager Console<\/strong>.<\/em><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3005 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/package-300x270-1.jpg\" alt=\"package-300x270\" width=\"300\" height=\"270\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/package-300x270-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/package-300x270-1-24x22.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3006 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/package-2-300x200-1.jpg\" alt=\"package-2-300x200\" width=\"300\" height=\"200\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/package-2-300x200-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/package-2-300x200-1-24x16.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Ap\u00f3s a adi\u00e7\u00e3o do package, vamos iniciar com a cria\u00e7\u00e3o de nossas Pages, a abordagem utilizada ser\u00e1 XAML. Por uma escolha\u00a0pessoal gosto sempre de separar as classes em folders para que fiquem mais leg\u00edveis \u00e0 solution.<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3007 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/final-solution-300x235-1.jpg\" alt=\"final-solution-300x235\" width=\"300\" height=\"235\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/final-solution-300x235-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/final-solution-300x235-1-24x19.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Expandindo a folder <strong>Pages,\u00a0<\/strong>obtemos os seguintes arquivos:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3008 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pages-files-300x101-1.jpg\" alt=\"pages-files-300x101\" width=\"300\" height=\"101\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pages-files-300x101-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pages-files-300x101-1-24x8.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>A folder <strong>Context<\/strong>, examinaremos com mais detalhes um pouco mais adiante, j\u00e1 a folder\u00a0<strong>Interfaces\u00a0<\/strong>cont\u00eam as interfaces que nossas Pages implementar\u00e3o\u00a0e que ser\u00e3o registradas em nosso container.<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3009 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pages-interfaces-300x162-1.jpg\" alt=\"pages-interfaces-300x162\" width=\"300\" height=\"162\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pages-interfaces-300x162-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pages-interfaces-300x162-1-24x13.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<pre class=\"lang:c# decode:true\" title=\"IPage interface.\">public interface IPage\r\n{\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Objeto que cont\u00eam propriedades que estar\u00e3o no contexto do Binding.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        object BindingContext { get; set; }\r\n \r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Exibe uma lista de a\u00e7\u00f5es que permitindo ao usu\u00e1rio sua escolha ( Apresenta\u00e7\u00e3o de forma nativa ).\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto apresentado na op\u00e7\u00e3o de cancelar&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"destruction\"&gt;&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"buttons\"&gt;Op\u00e7\u00f5es&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task&lt;string&gt; DisplayActionSheet(string title, string cancel, string destruction, params string[] buttons);\r\n \r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Apresenta uma caixa de di\u00e1logo com um \u00fanica op\u00e7\u00e3o de cancelar.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"message\"&gt;Mensagem&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto exibido no bot\u00e3o de cancelar.&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task DisplayAlert(string title, string message, string cancel);\r\n \r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Apresenta uma caixa de di\u00e1logo com um \u00fanica op\u00e7\u00e3o de cancelar.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"message\"&gt;Mensagem&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"accept\"&gt;Texto exibido no bot\u00e3o de confirma\u00e7\u00e3o&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto exibido no bot\u00e3o de cancelar.&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task&lt;bool&gt; DisplayAlert(string title, string message, string accept, string cancel);\r\n        \r\n}<\/pre>\n<p>A interface <strong>IPage<\/strong> apresenta alguns membros como propriedade e m\u00e9todos que as pr\u00f3prias <strong>Pages<\/strong> do Xamarin j\u00e1 implementam, estes por sua vez s\u00e3o os membros necess\u00e1rios que precisamos para as chamadas em nosso PageContext.<\/p>\n<pre class=\"lang:c# decode:true \">public interface IFirstPage : IPage\r\n{\r\n}\r\n\r\npublic interface ISecondPage : IPage\r\n{\r\n}\r\n\r\npublic interface IThirdPage : IPage\r\n{\r\n}<\/pre>\n<p>Estas s\u00e3o as demais interfaces da folder Pages\/Interfaces que ser\u00e3o\u00a0utilizadas em nosso container. Na estrutura das XAML Pages, temos:<\/p>\n<div id=\"crayon-571a4eb2e3c00433965818\" class=\"crayon-syntax crayon-theme-vs2012 crayon-font-consolas crayon-os-pc print-yes notranslate\">\n<pre class=\"lang:c# decode:true \" title=\"First Page.\">FirstPage.xaml\r\n\r\n&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;ContentPage xmlns=\"http:\/\/xamarin.com\/schemas\/2014\/forms\"\r\n             xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml\"\r\n             x:Class=\"XamarinSample.Pages.FirstPage\"&gt;\r\n  &lt;StackLayout \r\n        VerticalOptions=\"CenterAndExpand\" \r\n        HorizontalOptions=\"CenterAndExpand\"\r\n        BackgroundColor=\"Black\"&gt;\r\n    &lt;Image Source=\"microsoftHubRocks.png\" \/&gt;\r\n    \r\n    &lt;StackLayout Padding=\"10\"&gt;\r\n     &lt;Label Text=\"First Page \u00bb\" \/&gt;\r\n     &lt;Button Text=\"Go to Second Page\" \r\n            BackgroundColor=\"Green\" Command=\"{Binding GoToSecondPageCommand}\" \/&gt;\r\n    &lt;\/StackLayout&gt;\r\n  &lt;\/StackLayout&gt;\r\n&lt;\/ContentPage&gt;\r\n\r\n\r\nFirstPage.xaml.cs\r\n\r\nnamespace XamarinSample.Pages\r\n{\r\n    public partial class FirstPage : ContentPage, IFirstPage\r\n    {\r\n        #region Constructor\r\n\r\n        public FirstPage()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        #endregion\r\n    }\r\n}<\/pre>\n<p>Conectamos o behavior de Click do nosso <strong>Button\u00a0<\/strong>atrav\u00e9s da propriedade <strong>Command.<\/strong><\/p>\n<\/div>\n<pre class=\"lang:c# decode:true \" title=\"Second Page\">SecondPage.xaml\r\n\r\n&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;ContentPage xmlns=\"http:\/\/xamarin.com\/schemas\/2014\/forms\"\r\n             xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml\"\r\n             x:Class=\"XamarinSample.Pages.SecondPage\"&gt;\r\n  &lt;StackLayout\r\n       VerticalOptions=\"CenterAndExpand\"\r\n       HorizontalOptions=\"CenterAndExpand\"\r\n       BackgroundColor=\"Black\"&gt;\r\n    &lt;Image Source=\"microsoftHubRocks.png\" \/&gt;\r\n\r\n    &lt;StackLayout Padding=\"10\"&gt;\r\n      &lt;Label Text=\"Second Page \u00bb\" \/&gt;\r\n      &lt;Button Text=\"Go to Third Page\"\r\n             BackgroundColor=\"Green\" Command=\"{Binding GoToThirdPageCommand}\" \/&gt;\r\n    &lt;\/StackLayout&gt;\r\n  &lt;\/StackLayout&gt;\r\n&lt;\/ContentPage&gt;\r\n\r\nSecondPage.xaml.cs\r\n\r\nnamespace XamarinSample.Pages\r\n{\r\n    public partial class SecondPage : ContentPage, ISecondPage\r\n    {\r\n        #region Constructor\r\n\r\n        public SecondPage()\r\n        {\r\n            InitializeComponent();\r\n        } \r\n\r\n        #endregion\r\n    }\r\n}<\/pre>\n<pre class=\"lang:c# decode:true\" title=\"Thrid Page\">ThirdPage.xaml\r\n\r\n&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;ContentPage xmlns=\"http:\/\/xamarin.com\/schemas\/2014\/forms\"\r\n             xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml\"\r\n             x:Class=\"XamarinSample.Pages.ThirdPage\"&gt;\r\n\r\n  &lt;StackLayout\r\n       VerticalOptions=\"CenterAndExpand\"\r\n       HorizontalOptions=\"CenterAndExpand\"\r\n       BackgroundColor=\"Black\"&gt;\r\n    &lt;Image Source=\"microsoftHubRocks.png\" \/&gt;\r\n\r\n    &lt;StackLayout Padding=\"10\"&gt;\r\n      &lt;Label Text=\"Third Page \u00bb\" \/&gt;\r\n      &lt;Button Text=\"Show Message\"\r\n             BackgroundColor=\"Green\" Command=\"{Binding ShowCustomMessageCommand}\"\/&gt;\r\n    &lt;\/StackLayout&gt;\r\n  &lt;\/StackLayout&gt;\r\n\r\n&lt;\/ContentPage&gt;\r\n\r\n\r\nThirdPage.xaml.cs\r\n\r\nusing Xamarin.Forms;\r\nusing XamarinSample.Pages.Interfaces;\r\n\r\nnamespace XamarinSample.Pages\r\n{\r\n    public partial class ThirdPage : ContentPage, IThirdPage\r\n    {\r\n        #region Constructor\r\n\r\n        public ThirdPage()\r\n        {\r\n            InitializeComponent();\r\n        } \r\n        \r\n        #endregion\r\n    }\r\n}<\/pre>\n<p>Agora que nossas Pages est\u00e3o constru\u00eddas, vamos visualizar as viewmodels que se encontram na seguinte estrutura:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3010 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/viewmodel-files.png\" alt=\"viewmodel-files\" width=\"288\" height=\"200\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/viewmodel-files.png 288w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/viewmodel-files-24x17.png 24w\" sizes=\"(max-width: 288px) 100vw, 288px\" \/><\/p>\n<p>Lembrando que para que haja uma viewmodel a mesma deve implementar a interface\u00a0<strong>INotifyPropertyChanged ,\u00a0<\/strong>para que a mesma possa responder \u00e0s notifica\u00e7\u00f5es; para evitar o retrabalho a ViewModelBase se encarrega desta implementa\u00e7\u00e3o.<\/p>\n<pre class=\"lang:c# decode:true\" title=\"ViewModel Base.\">  public abstract class ViewModelBase : IViewModel\r\n    {\r\n        #region Properties\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Contexto de navega\u00e7\u00e3o e mensagens pop-up.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public IPageContext Context { get; private set; }\r\n\r\n        #endregion\r\n\r\n        #region Constructor\r\n\r\n        public ViewModelBase(IPageContext context)\r\n        {\r\n            Context = context;\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region INotifyPropertyChanged members\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/ Ocorre quando h\u00e1 mudan\u00e7as em propriedades.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public event PropertyChangedEventHandler PropertyChanged;\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Notifica \u00e0s modifica\u00e7\u00f5es.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;typeparam name=\"T\"&gt;Tipo da Propriedade.&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;param name=\"expression\"&gt;Propriedade&lt;\/param&gt;\r\n        protected void RaisedPropertyChanged&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt; expression)\r\n        {\r\n            var memberExpression = expression.Body as MemberExpression;\r\n            if (memberExpression == null) return;\r\n\r\n            var propertyInfo = memberExpression.Member as PropertyInfo;\r\n            if (propertyInfo == null) return;\r\n\r\n            RaisedPropertyChanged(propertyInfo.Name);\r\n        }\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Notifica \u00e0s modifica\u00e7\u00f5es.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"propertyName\"&gt;Nome da Propriedade&lt;\/param&gt;\r\n        protected void RaisedPropertyChanged([CallerMemberName] string propertyName = null)\r\n        {\r\n            if (PropertyChanged != null)\r\n                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));\r\n        }\r\n\r\n        #endregion\r\n\r\n    }<\/pre>\n<p>Seguindo com as demais:<\/p>\n<pre class=\"lang:c# decode:true\" title=\"First ViewModel\">    public class FirstViewModel : ViewModelBase, IFirstViewModel\r\n    {\r\n        #region Fields\r\n\r\n        private Command _goToSecondPageCommand;\r\n\r\n        #endregion\r\n\r\n        #region Constructor\r\n\r\n        public FirstViewModel(IPageContext context)\r\n            : base(context)\r\n        { }\r\n\r\n        #endregion\r\n\r\n        #region IFistViewModel members\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Commando respons\u00e1vel por navegar para a segunda p\u00e1gina.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public ICommand GoToSecondPageCommand\r\n        {\r\n            get\r\n            {\r\n                return _goToSecondPageCommand ??\r\n                      (_goToSecondPageCommand = new Command(async() =&gt; \r\n                        await Context.NavigateTo&lt;ISecondPage, ISecondViewModel&gt;()));\r\n            }\r\n        } \r\n\r\n        #endregion\r\n    }\r\n\r\n\r\n\r\n public interface IFirstViewModel\r\n    {\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Commando respons\u00e1vel por navegar para a segunda p\u00e1gina.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        ICommand GoToSecondPageCommand { get; }\r\n    }<\/pre>\n<pre class=\"lang:c# decode:true \" title=\"Second ViewModel.\"> public class SecondViewModel : ViewModelBase, ISecondViewModel\r\n    {\r\n        #region Fields\r\n\r\n        private Command _goToThirdPageCommand;\r\n\r\n        #endregion\r\n\r\n        #region Constructor\r\n\r\n        public SecondViewModel(IPageContext context)\r\n            : base(context)\r\n        { }\r\n\r\n        #endregion\r\n\r\n        #region ISecondViewModel members\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Commando respons\u00e1vel por navegar para a terceira p\u00e1gina.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public ICommand GoToThirdPageCommand\r\n        {\r\n            get\r\n            {\r\n                return _goToThirdPageCommand ??\r\n                      (_goToThirdPageCommand = new Command(async() =&gt;\r\n                        await Context.NavigateTo&lt;IThirdPage, IThirdViewModel&gt;()));\r\n            }\r\n        }\r\n\r\n        #endregion\r\n    }\r\n\r\n\r\n  public interface ISecondViewModel\r\n    {\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Commando respons\u00e1vel por navegar para a terceira p\u00e1gina.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        ICommand GoToThirdPageCommand { get; }\r\n    }<\/pre>\n<pre class=\"lang:c# decode:true \" title=\"Thrid ViewModel\">public class ThirdViewModel : ViewModelBase, IThirdViewModel\r\n{\r\n        #region Fields\r\n\r\n        private Command _showCustomMessageCommand;\r\n\r\n        #endregion\r\n\r\n        #region Constructor\r\n\r\n        public ThirdViewModel(IPageContext context)\r\n            : base(context)\r\n        { }\r\n\r\n        #endregion\r\n\r\n        #region IThirdViewModel members\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Commando respons\u00e1vel por exibir mensagem.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public ICommand ShowCustomMessageCommand\r\n        {\r\n            get\r\n            {\r\n                return _showCustomMessageCommand ??\r\n                      (_showCustomMessageCommand = new Command(async() =&gt;\r\n                      {\r\n                          await Context.ShowMessage(\"Mensagem\", \"PageContext com mensagem.\", \"Ok\");\r\n                      }));\r\n            }\r\n        }\r\n\r\n        #endregion\r\n    }\r\n\r\n\r\n\r\n public interface IThirdViewModel\r\n    {\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Commando respons\u00e1vel por exibir mensagem.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        ICommand ShowCustomMessageCommand { get; }\r\n    }<\/pre>\n<p>Podemos observar que as viewmodels n\u00e3o possuem instancias das Pages, temos somente uma propriedade chamada PageContext que \u00e9 setada por inje\u00e7\u00e3o do container. Desta forma temos o PageContext apresentado na seguinte estrutura:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3011 aligncenter\" src=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pagecontext-files-300x89-1.jpg\" alt=\"pagecontext-files-300x89\" width=\"300\" height=\"89\" srcset=\"https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pagecontext-files-300x89-1.jpg 300w, https:\/\/www.mxcursos.com\/blog\/wp-content\/uploads\/2016\/04\/pagecontext-files-300x89-1-24x7.jpg 24w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>A interface IPageContext exp\u00f5e os\u00a0membros para Navigation e Messaging:<\/p>\n<pre class=\"lang:c# decode:true\" title=\"IPageContext interface\"> public interface IPageContext\r\n    {\r\n        \/\/ &lt;summary&gt;\r\n        \/\/ Obt\u00e9m a IPage atual.\r\n        \/\/ &lt;\/summary&gt;\r\n        IPage CurrentPage { get; }\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Navega para uma TPage conectada a uma TViewModel.\r\n        \/\/\/ Modelo de navega\u00e7\u00e3o baseado na NavigationStack.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;typeparam name=\"TPage\"&gt;Nova p\u00e1gina&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;typeparam name=\"TViewModel\"&gt;Viewmodel&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task NavigateTo&lt;TPage, TViewModel&gt;()\r\n           where TPage : class, IPage\r\n           where TViewModel : class;\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Navega para uma TPage conectada a uma TViewModel, fazendo uma inje\u00e7\u00e3o do valor para uma propriedade\r\n        \/\/\/ desta viewmodel.\r\n        \/\/\/ Modelo de navega\u00e7\u00e3o baseado na NavigationStack.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;typeparam name=\"TPage\"&gt;Nova p\u00e1gina&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;typeparam name=\"TViewModel\"&gt;Viewmodel&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;param name=\"property\"&gt;Proprieda&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"value\"&gt;Valor&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task NavigateTo&lt;TPage, TViewModel&gt;(Expression&lt;Func&lt;object&gt;&gt; property, object value)\r\n            where TPage : class, IPage\r\n            where TViewModel : class;\r\n        \r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Navega para uma TPage conectada a uma TViewModel.\r\n        \/\/\/ Modelo de navega\u00e7\u00e3o baseado na ModalStack.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;typeparam name=\"TPage\"&gt;Nova p\u00e1gina&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;typeparam name=\"TViewModel\"&gt;Viewmodel&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task ModalNavigateTo&lt;TPage, TViewModel&gt;()\r\n           where TPage : class, IPage\r\n           where TViewModel : class;\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Exibe uma lista de a\u00e7\u00f5es que permitindo ao usu\u00e1rio sua escolha ( Apresenta\u00e7\u00e3o de forma nativa ).\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto apresentado na op\u00e7\u00e3o de cancelar&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"destruction\"&gt;&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"buttons\"&gt;Op\u00e7\u00f5es&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task&lt;string&gt; ShowConfirmationMessage(string title, string cancel, string destruction, params string[] buttons);\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Apresenta uma caixa de di\u00e1logo com um \u00fanica op\u00e7\u00e3o de cancelar.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"message\"&gt;Mensagem&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto exibido no bot\u00e3o de cancelar.&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task ShowMessage(string title, string message, string cancel);\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Apresenta uma caixa de di\u00e1logo com um \u00fanica op\u00e7\u00e3o de cancelar.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"message\"&gt;Mensagem&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"accept\"&gt;Texto exibido no bot\u00e3o de confirma\u00e7\u00e3o&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto exibido no bot\u00e3o de cancelar.&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        Task&lt;bool&gt; ShowMessage(string title, string message, string accept, string cancel);\r\n\r\n    }<\/pre>\n<p>E sua implementa\u00e7\u00e3o:<\/p>\n<pre class=\"lang:c# decode:true \" title=\"PageContext class.\">  public class PageContext : IPageContext\r\n    {\r\n\r\n        #region Fields\r\n\r\n        private IComponentContext _componentContext;\r\n        private IPage _page;\r\n\r\n        #endregion\r\n\r\n        #region Properties\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Obt\u00e9m a IPage atual.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public IPage CurrentPage\r\n        {\r\n            get\r\n            {\r\n                var xamarinPage = _page as Page;\r\n                if (xamarinPage == null) return null;\r\n\r\n                var stack = xamarinPage.Navigation.NavigationStack;\r\n\r\n                return stack.Any() ? stack.Last() as IPage : _page;\r\n            }\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region Constructor\r\n\r\n        public PageContext(IComponentContext componentContext, IPage page)\r\n        {\r\n            _componentContext = componentContext;\r\n            _page = page;\r\n        }\r\n        #endregion\r\n\r\n        #region Methods\r\n\r\n        #region Navigation\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Navega para uma TPage conectada a uma TViewModel.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;typeparam name=\"TPage\"&gt;Nova p\u00e1gina&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;typeparam name=\"TViewModel\"&gt;Viewmodel&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        public async Task NavigateTo&lt;TPage, TViewModel&gt;()\r\n            where TPage : class, IPage\r\n            where TViewModel : class\r\n        {\r\n            \/\/Resolvendo depend\u00eancias.\r\n            var newPage = _componentContext.Resolve&lt;TPage&gt;();\r\n            var viewmodel = _componentContext.Resolve&lt;TViewModel&gt;();\r\n\r\n            if (newPage != null &amp;&amp; viewmodel != null)\r\n            {\r\n                \/\/Conectando a Nova View com a Viewmodel.\r\n                newPage.BindingContext = viewmodel;\r\n                \/\/Empilhando a p\u00e1gina atual.\r\n                await ((Page)CurrentPage).Navigation.PushAsync(newPage as Page);\r\n            }\r\n        }\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Navega para uma TPage conectada a uma TViewModel, fazendo uma inje\u00e7\u00e3o do valor para uma propriedade\r\n        \/\/\/ desta viewmodel.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;typeparam name=\"TPage\"&gt;Nova p\u00e1gina&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;typeparam name=\"TViewModel\"&gt;Viewmodel&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;param name=\"property\"&gt;Proprieda&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"value\"&gt;Valor&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        public async Task NavigateTo&lt;TPage, TViewModel&gt;(Expression&lt;Func&lt;object&gt;&gt; property, object value)\r\n            where TPage : class, IPage\r\n            where TViewModel : class\r\n        {\r\n            \/\/Resolvendo depend\u00eancias.\r\n            var newPage = _componentContext.Resolve&lt;TPage&gt;();\r\n            var viewmodel = _componentContext.Resolve&lt;TViewModel&gt;();\r\n\r\n            if (newPage != null &amp;&amp; viewmodel != null)\r\n            {\r\n                \/\/Conectando a Nova View com a Viewmodel.\r\n                newPage.BindingContext = viewmodel;\r\n                \/\/Definindo valor para uma propriedade da Viewmodel.\r\n                SetPropertyValue&lt;TViewModel&gt;(property.Body, viewmodel, value);\r\n                \/\/Empilhando a p\u00e1gina atual.\r\n                await ((Page)CurrentPage).Navigation.PushAsync(newPage as Page);\r\n            }\r\n        }\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Navega para uma TPage conectada a uma TViewModel.\r\n        \/\/\/ Modelo de navega\u00e7\u00e3o baseado na ModalStack.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;typeparam name=\"TPage\"&gt;Nova p\u00e1gina&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;typeparam name=\"TViewModel\"&gt;Viewmodel&lt;\/typeparam&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        public async Task ModalNavigateTo&lt;TPage, TViewModel&gt;()\r\n            where TPage : class, IPage\r\n            where TViewModel : class\r\n        {\r\n            \/\/Resolvendo depend\u00eancias.\r\n            var newPage = _componentContext.Resolve&lt;TPage&gt;();\r\n            var viewmodel = _componentContext.Resolve&lt;TViewModel&gt;();\r\n\r\n            if (newPage != null &amp;&amp; viewmodel != null)\r\n            {\r\n                \/\/Conectando a Nova View com a Viewmodel.\r\n                newPage.BindingContext = viewmodel;\r\n                \/\/Empilhando a p\u00e1gina atual.\r\n                await ((Page)CurrentPage).Navigation.PushModalAsync(newPage as Page);\r\n            }\r\n        }\r\n\r\n        private void SetPropertyValue&lt;T&gt;(Expression property, object root, object value)\r\n        {\r\n            var member = property as MemberExpression;\r\n            if (member == null) return;\r\n\r\n            var propertyInfo = member.Member as PropertyInfo;\r\n            if (propertyInfo == null) return;\r\n\r\n            var propertySetter = root.GetType()\r\n                                .GetTypeInfo()\r\n                                .DeclaredProperties\r\n                                .First(c =&gt; c.Name.Equals(propertyInfo.Name, StringComparison.OrdinalIgnoreCase));\r\n\r\n            if (propertySetter != null)\r\n                propertySetter.SetValue(root, value);\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region Messaging\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Exibe uma lista de a\u00e7\u00f5es que permitindo ao usu\u00e1rio sua escolha ( Apresenta\u00e7\u00e3o de forma nativa ).\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto apresentado na op\u00e7\u00e3o de cancelar&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"destruction\"&gt;&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"buttons\"&gt;Op\u00e7\u00f5es&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        public async Task&lt;string&gt; ShowConfirmationMessage(string title, string cancel, string destruction, params string[] buttons)\r\n        {\r\n            var result = await CurrentPage.DisplayActionSheet(title, cancel, destruction, buttons);\r\n            return result;\r\n        }\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Apresenta uma caixa de di\u00e1logo com um \u00fanica op\u00e7\u00e3o de cancelar.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"message\"&gt;Mensagem&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto exibido no bot\u00e3o de cancelar.&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        public async Task ShowMessage(string title, string message, string cancel)\r\n        {\r\n            await CurrentPage.DisplayAlert(title, message, cancel);\r\n        }\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Apresenta uma caixa de di\u00e1logo com um \u00fanica op\u00e7\u00e3o de cancelar.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=\"title\"&gt;T\u00edtulo&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"message\"&gt;Mensagem&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"accept\"&gt;Texto exibido no bot\u00e3o de confirma\u00e7\u00e3o&lt;\/param&gt;\r\n        \/\/\/ &lt;param name=\"cancel\"&gt;Texto exibido no bot\u00e3o de cancelar.&lt;\/param&gt;\r\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n        public async Task&lt;bool&gt; ShowMessage(string title, string message, string accept, string cancel)\r\n        {\r\n            var result = await CurrentPage.DisplayAlert(title, message, accept, cancel);\r\n            return result;\r\n        }\r\n\r\n        #endregion\r\n\r\n        #endregion\r\n    }<\/pre>\n<p>Vamos detalhar nossa PageContext:<\/p>\n<ul>\n<li>A propriedade de CurrentPage retorna a IPage atual;<\/li>\n<li>O construtor da classe PageContext, recebe IComponentContext, que \u00e9 o pr\u00f3pria inst\u00e2ncia do container, para que possamos recuperar as implementa\u00e7\u00f5es tardiamente, e recebemos tamb\u00e9m uma IPage que \u00e9 inserida como a primeira p\u00e1gina da Stack de navega\u00e7\u00e3o.<\/li>\n<li>Nos m\u00e9todos de navega\u00e7\u00e3o recebemos nos placeholders uma page (TPage) e uma viewmodel (TViewmodel), ambas s\u00e3o\u00a0refer\u00eancias para as inst\u00e2ncias recuperadas no container, as conectamos pelo BindingContext da Page e em seguida utilizamos o sistema de Navega\u00e7\u00e3o do Xamarin.Forms;<\/li>\n<li>O m\u00e9todo <strong>SetPropertyValue\u00a0<\/strong>\u00e9 utilizado para setarmos uma propriedade da viewmodel.<\/li>\n<li>Por final temos os m\u00e9todos de Messaging que s\u00e3o um wrapper para os m\u00e9todos utilizados no Xamarin.Forms que est\u00e3o presentes dentro de <strong>Page<\/strong>.<\/li>\n<\/ul>\n<p>Desta forma em nossas\u00a0implementa\u00e7\u00f5es nas viewmodels temos o Context chamando o m\u00e9todo de NavigateTo passando a interface da Page e Viewmodel, que ser\u00e3o resolvidas pelo container e o m\u00e9todo ShowMessage para apresenta\u00e7\u00e3o das mensagens.<\/p>\n<pre class=\"lang:c# decode:true\">public ICommand GoToThirdPageCommand\r\n{\r\n   get\r\n   {\r\n       return _goToThirdPageCommand ??\r\n             (_goToThirdPageCommand = new Command(async() =&gt;\r\n             await Context.NavigateTo&lt;IThirdPage, IThirdViewModel&gt;()));\r\n   }\r\n}<\/pre>\n<pre class=\"lang:c# decode:true \">  \/\/\/ &lt;summary&gt;\r\n  \/\/\/ Commando respons\u00e1vel por exibir mensagem.\r\n  \/\/\/ &lt;\/summary&gt;\r\n  public ICommand ShowCustomMessageCommand\r\n  {\r\n      get\r\n      {\r\n           return _showCustomMessageCommand ??\r\n                  (_showCustomMessageCommand = new Command(async() =&gt;\r\n                  {\r\n                      await Context.ShowMessage(\"Mensagem\", \"PageContext com mensagem.\", \"Ok\");\r\n                   }));\r\n      }\r\n  }<\/pre>\n<p>Antes de finalizarmos vamos \u00e0 configura\u00e7\u00e3o do nosso container.<\/p>\n<pre class=\"lang:c# decode:true \"> public class AutofacConfig\r\n    {\r\n\r\n        #region Fields\r\n\r\n        private static IContainer _container;\r\n\r\n        #endregion\r\n\r\n        #region Properties\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Recupera uma page do cont\u00e2iner.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public static TPage GetPage&lt;TService, TPage&gt;()\r\n            where TService : IPage\r\n            where TPage : class\r\n        {\r\n            if (_container == null || !_container.IsRegistered&lt;TService&gt;())\r\n                return default(TPage);\r\n\r\n            var pageContext = _container.Resolve&lt;IPageContext&gt;();\r\n            return (TPage)pageContext.CurrentPage;\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region Methods\r\n\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Respons\u00e1vel por registras em depend\u00eancias ( Autofac ).\r\n        \/\/\/ &lt;\/summary&gt;\r\n        public static void ConfigureContainer()\r\n        {\r\n            var builder = new ContainerBuilder();\r\n\r\n            \/\/Pages\r\n            builder.Register(c =&gt; new FirstPage()).As&lt;IFirstPage&gt;()\r\n                .OnActivated(e =&gt; e.Instance.BindingContext = e.Context.Resolve&lt;IFirstViewModel&gt;());\r\n            builder.RegisterType&lt;SecondPage&gt;().As&lt;ISecondPage&gt;();\r\n            builder.RegisterType&lt;ThirdPage&gt;().As&lt;IThirdPage&gt;();\r\n\r\n            \/\/Viewmodels\r\n            builder.RegisterType&lt;FirstViewModel&gt;().As&lt;IFirstViewModel&gt;();\r\n            builder.RegisterType&lt;SecondViewModel&gt;().As&lt;ISecondViewModel&gt;();\r\n            builder.RegisterType&lt;ThirdViewModel&gt;().As&lt;IThirdViewModel&gt;();\r\n\r\n            \/\/PageContext\r\n            builder.Register((c, p) =&gt; new PageContext(c.Resolve&lt;IComponentContext&gt;(), c.Resolve&lt;IFirstPage&gt;()))\r\n                .As&lt;IPageContext&gt;()\r\n                .SingleInstance();\r\n\r\n            _container = builder.Build();\r\n        }\r\n\r\n        #endregion\r\n    }<\/pre>\n<p>O m\u00e9todo GetPage nos auxilia na inicializa\u00e7\u00e3o do PageContext e definir \u00e0 Page de inicializa\u00e7\u00e3o na classe Application.<\/p>\n<p>Lembre-se de inicializar a configura\u00e7\u00e3o do container.<\/p>\n<p>Este helper\u00a0n\u00e3o contempla todas as poss\u00edveis chamadas e navega\u00e7\u00e3o do Xamarin.Forms, mas para isso basta implement\u00e1-los de acordo com \u00e0 necessidade. A utiliza\u00e7\u00e3o do PageContext \u00e9 interessante pois inibe a utiliza\u00e7\u00e3o da Page e seus membros, o que poderia deixar as viewmodels completamente amarradas. Espero que curtam <strong>PageContext,\u00a0<\/strong>sauda\u00e7\u00f5es <strong>MXCursos<\/strong>\u00a0!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Oi pessoal do MX Cursos, hoje vamos falar de PageContext, algu\u00e9m j\u00e1 ouviu falar ? N\u00e3o? Ent\u00e3o, este foi um termo que utilizei j\u00e1 que estaremos tratando no pr\u00f3prio contexto das Pages no Xamarin.Forms e o nome parece ser bem fiel\u2026 Em um r\u00e1pido preview apresentaremos um diagrama simples para esbo\u00e7ar um projeto cujo sua [&hellip;]<\/p>\n","protected":false},"author":152,"featured_media":3014,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[678],"tags":[],"class_list":["post-2998","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvimento"],"_links":{"self":[{"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/posts\/2998","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/users\/152"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/comments?post=2998"}],"version-history":[{"count":0,"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/posts\/2998\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/media\/3014"}],"wp:attachment":[{"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/media?parent=2998"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/categories?post=2998"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mxcursos.com\/blog\/wp-json\/wp\/v2\/tags?post=2998"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}