I need your feedback, and I need it now! I have been working on the next version of Prism for Xamarin.Forms and need your help making sure I’m adding value and solving issues that prevent you from being productive. As of now, you can download the latest Prism for Xamarin.Forms 6.3 Preview from NuGet.
Check out the available NuGet packages here: https://github.com/PrismLibrary/Prism/blob/master/docs/NuGet-Packages.md
I have added a number of new features and improvements based on community feedback, and some of these changes will be breaking. Yes, I know… I hate releasing breaking changes. It annoys me just as much as it annoys you, but sometimes to move something forward we have to correct past oversights and bad decisions. So let’s take a quick look at what you can expect to see and break in this newest 6.3 Preview.
DelegateCommand.FromAsyncHandler is Obsolete
Yes, you read that correctly. DelegateCommand has this static methods that allows you to create an “async command”. The Microsoft team added this in the v5 release and I have never really given it much thought since. Until recently, when a number of people have noticed many issues with DelegateCommand not working as expected. Long story short, trying to have DelegateCommand act async is a bad idea, and needs to be fixed ASAP. You can read more about here is my last post announcing this. This will be a breaking change when we RTM 6.3.
OnNavigatingTo added to INavigationAware – Breaking
Based on very popular demand, there is a new OnNavigatingTo method being added to the INavigationAware interface. This method was added to fix the issue of trying to initialize ViewModels with data being passed in as parameters. Currently, if you pass parameters to the target ViewModel and set properties, there is a visible delay when the View updates to reflect those values. This is because the View has already been pushed onto the navigation stack, and then the bindings are updated after the properties have been set. Now, you can use the new OnNavigatingTo, which is called before the target View is pushed onto the navigation stack, in order to initialize your data. Now, you will no longer have that delay in displaying your data.
IConfirmNavigation/IConfirmNavigationAsync changes – Breaking
This is probably not that big of a deal, but the IConfirmNavigation and IConfirmNavigationAsync interfaces no longer depend on the INavigationAware interface. I had a ton of feedback that when using IConfirmNavigation, you may not always be dealing with handling the INavigationAware methods. So this dependency has been removed. Chances are, you won’t even notice it.
Hardware/software back button support
This was a major limitation in the Prism navigation service. Previously, when you would use the hardware back buttons, or the software back button to navigate back to a previous View, the INavitaionAware methods would never fire. This has now been fixed! The only limitation is when using the hardware/software back buttons, the new OnNavigatingTo method will not be invoked. Only the OnNavigatedFrom and OnNavigatedTo methods will be invoked. This is because when using the hardware/software back buttons, I have no way of invoking the OnNavigatingTo prior to the popping action occurring.
Another pain point in Xamarin.Forms development is memory leaks. Xamarin.Forms is notorious for not cleaning itself up. So, now you can use the IDestructible interface for both Views and ViewModels to clean up any resources you may have. Remove event handlers, unregister from CompositeCommands, close any streams that may be open. Whatever you need. I know what you are going to ask, “but Brian, why didn’t you use IDisposable?”. Well, I tried, but then quickly realized that Prism shouldn’t be the one calling IDisposable. Doing so caused a number of issues and exceptions. So, I had to introduce this new interface.
Another need feature is that TabbedPages can now be IActiveAware. This means that when the ViewModels of your tabs implement IActiveAware, Prism will keep track of which tab is the active tab. This is very powerful when combined with CompositeCommands.
The last feature that was added was a new IDeviceService interface which gives you access to the Xamarin.Froms Device properties and methods. You can now perform Device functions without having to reference a static class in your ViewModels. You are just a little more testable now.
Prism Template Pack
Besides improving the Prism for Xamarin.Forms platform, I also made a number of improvements to the Prism Template Pack.
The project template dialog got a new face lift thanks to the designers at Infragistics. So now it looks much prettier.
There was also a nice productivity change to the item templates provided in the Prism Template Pack. Now when you add a new View by selecting Add New Item –> Prism –> Xamarin.Forms –> Page, not only do you get a new Page, but you get a ViewModel, and the Page is registered for navigation for you automatically in the App.xaml.cs file. Now, you don’t have to do anything! Prism does it for you.
Add a new view:
A View and ViewModel are added to your project:
And the View is registered for navigation automatically:
Hopefully these new Prism Template Pack changes help you be more productive and take away some of that busy work.
As you can see, I have been hard at work trying to add value to Prism for Xamarin.Forms and make you more productive at the same time. Make sure to check out the release notes for a list of all the changes. Please test out all these new features shipping in the new preview. Prepare your apps for the breaking changes.
I will be working on updating the documentation, which as you know is always the last thing that a developer does. I will also work on getting some new samples in the repo that covers all the cool features Prism for Xamarin.Forms provides. I am also starting work on a brand new Prism for Xamarin.Forms Pluralsight course. So keep an eye out on my course list which can be seen on my author page for this new course.
Please, get involved with the project on GitHub. Be sure to provide your feedback, submit issues, submit features, and submit PR’s. This is your project, so make it what you want it to be. As always, feel free contact me on my blog, connect with me on Twitter (@brianlagunas), or leave a comment below for any questions or comments you may have.
First, thank you for all the work you’re doing!
I have an off-topic question maybe, about Xamarin Forms:
“Another pain point in Xamarin.Forms development is memory leaks. Xamarin.Forms is notorious for not cleaning itself up.”
It would be very useful for someone like me who has started working with Xamarin Forms to read about the pain points. Would you be interested in sharing some stories about that? Not sure, maybe blog about it in a separate post.
(by the way, in latest Chrome on Windows 10, I can’t click on the comment input to start typing, it doesn’t focus. I need to click in the Email input first and then Tab to the comment input).
Just go to the Xamarin forums and search for “memory leak”. Then scroll through 44 pages of results 🙂
Thank you for all the great work you are putting into this framework. It just happened that I was checking the memory usage of one simple page yesterday in XF which was growing and growing.
It was a very simple test page with a memory stream reading from a resource and putting the content into a webview.
I will take out version 6.3 for a spin.
This is an issue with XF, not Prism. In 6.3 preview, I have added a new IDestructible interface that will allow you to clean up your VIews and VMs. Something that XF doesn’t allow you to do out of the box.
Brian, you are doing a awesome work, thanks for help the community with this great Framework.
Brian, Keep up the good work and it was great talking to you about the work you have been doing while at the MVP Summit. I am very much looking forward to OnNavigatingTo.
Also, the odd behavior in the comment section seems to happen in Safari as well. I had to click into Name field and then tab to Email and again to get to Comment.
Hi Brian, Is there a way to pass parameters to the constructor of the target page while navigating in Prism. I am navigating to a tabbed page where I want to add tabs based on a value from the calling page.
Thank you for all your efforts towards Prism. I have been playing with the 6.3 features and it is amazing
No. That is not how you should be passing parameters. You need to be using the INavigationAware methods. Just so you know, you can use INavigationAware on the Page class too. It’s not limited to the VM.
I am just starting a project with Xamarin.Forms and Prism. Thanks a lot for your great work!
I would like to use DesignData with the XAML Previewer like it is explained in http://motzcod.es/post/143702671962/xamarinforms-xaml-previewer-design-time-data
Unfortunatley this does not work – I think because of the ViewModelLocator of Prism.
Am I right and is a solution for that planed?
Thanks for an answer…
This works just fine. You have to set the BindingContext to a static instance in XAML. At run time the ViewModelLocator will override the BindingContext and work as expected.
Hello Brian, how possible is to remove Xamarin.Forms dependency from Prism.Forms? I know it is “hard” dependency, but it really limits usage of Prism. ViewModels are not transferable to WPF.
You can’t. It’s impossible. It doesn’t limit the usage of Prism at all. The only limits you will have is how you architect your applications and how you share your VMs. You need to have a base VM that contains all your shared logic, then have platform specific VMs that derive from your base VMs to hold all the platform specific code such as navigation. I have never had an issue sharing across from XF to WPF or UWP.
For me it is impossible, but for you it is possible:)
Other MVVM frameworks (such mvvmcross) do not have such dependency and it simplifies multiplatforming between XF and WPF etc. Using Prism I must think of multiplatform architecture, create base shared logic and then platform specific… in my opinion it is unnecessary.
Prism is more than just MVVM. Those other frameworks do not do what Prism does, and that is why they can not have any dependency on their target platform. For example; navigation. Navigation cannot be shared across all platforms. It must be specific to the platform. Just so you know, Prism.dll does not have any dependencies on any UI technologies. So you can easily use everything in the Prism.Core NuGet package in your base VMs no problem. Once you get into platform specifics, you needs to start using Prism.Forms, Prism.Windows, and Prism.Wpf to achieve that functionality. Trying to compare Prism with those other frameworks is like comparing a jet to bicycles.
If you are building a cross platform app using shared code, services and tests, and you are not thinking of a multiplatform architecture then you are doing it wrong.
The good news is that if Prism doesn’t suite your needs, there are a ton of other options out there that you can use. That’s what makes our community so great.
OK, so take full advantage from Xamarin navigation it is needed to use Xamarin.Forms dependency. Creating some abstract above this mechanism would limit features, am I right?
And one more thing about navigation. From my research navigation works like that (in short):
From ViewModel we call navigation method with NAME of destination PAGE.
Prism container resolves instance of PAGE based on NAME.
Prism creates VIEWMODEL for PAGE using for example DefaultViewModelFactory
Prism attaches VIEWMODEL to PAGE BindingContext.
My question is why ViewModel is created base on PAGE and not contrary? I thing that PAGE should be created base on ViewModel so the above steps would be:
From ViewModel we call navigation method with NAME of destination VIEWMODEL.
Prism container resolves instance of VIEWMODEL based on NAME.
Prism creates PAGE for VIEWMODEL using for example DefaultPageFactory
Prism attaches VIEWMODEL to PAGE BindingContext.
In my opinion this approach is more MVVM – view should be created base on viewmodel, navigation should be placed in viewmodel. Maybe it is because of Xamarin.Forms navigation nature ( because navigation is placed in Page)?
I think you are overthinking it a bit. You are not navigating to a Page from within a VM. You are navigating to a key, a simple string identifier that represents your navigation target. You don’t know if it is a Page or a VM, and you don’t care. What the framework does behind the scenes to actually perform the navigation does not matter to you.
If you think that navigating to a VM is more “MVVM-ish” , then I think you don’t have a good understanding of what MVVM really is. Let me ask you this… why does it matter what is created first? What is the benefit? What do you get out of it? Navigation is in the VM no matter what object is created first, and you are not referencing neither a View or a VM when navigating. You navigate to a key, and that is all you know when navigating.
I totally agree with idea of navigation to “something” using just key. For me there was not matter what framework does behind scenes until I came across “nesting ViewModel” approach. Nesting ViewModels means that application (in my case dynamically) creates ViewModel that has others ViewModels as public properties (also created dynamically) and this ViewModels also has nested ViewModels and so on… So root ViewModel (for example PageViewModel) consists of tree of other ViewModels. Each ViewModel has its own View representation. So now whole view for root ViewModel is also created as a view tree based on tree of ViewModels. I hope I described clearly what I mean. This approach seems very MVVM-ish and now it really matters what is created first. And according nesting ViewModels – this solution seems to allow to create really dynamic, easy to maintain applications. I say “seems” because I am in the middle of work and I do not have full experience with it.
Prism’s approach of Page first creation does not exclude it from using – I think Prism is still the best choice. It is just needed to create some additional mechanism. But from this perspective the subtle difference of creation order really matters.
And in case of Prism navigation is not quite behind scenes because it is needed to provide Page factory and ViewModel factory. This factories requires Page-first approach because ViewModel factory gets Page instance. Am I right?
What you are doing is not really “MVVM-ish”. You are overcomplicating it. I don’t know where you have learned this very unorthodox way of using MVVM, but I would not recommend that at all. That is already a nasty architecture and very coupled to other VM’s and classes in your app domain, and it will be very slow and difficult to test. Although that nested VM approach might work in WPF, it will not work for Xamarin.Forms because the templating features needed to support it don’t exist in XF. Prism does not use any kind of Page or VM factory, so I’m not sure what you are talking about here. Good luck
Hmm, it is complicated, but possible in Xamarin.Forms – I have already tested it with success. However I do not know if it will be slow or not – soon I will see. This approach is needed for creating dynamic application framework so I think is worth to try. And according Page and VM factories: I am talking about Page resolving using Container in UnityPageNavigationService (Container may resolve Page using passed factory) and VM resolving using ViewModelLocationProvider.SetDefaultViewModelFactory() method.
Thank you for wishing luck, also good luck to you.
🙂 OK !
Hi brian, currently using prism on two projects, and prism is amazing i haven’t any issue so far and i can recommend this to my fellow xamarin devs community here in the Philippines.
That is great to hear. Thank you for your support and kind words.
When i use command “return Task.CompletedTask;”, IDE show error ‘Task’ does not contain a definition for ‘CompletedTask’. I search on Google and see that it may be target framework should be 4.6+ (the current target is 4.5). But, i can not change target to 4.6 cause of this’s portable (we only change with non-portable project???). Show, how can i use Task.CompletedTask or may be an other way ? Thanks!
I’m sorry, but this issue is not related to this post or Prism. I would suggest asking your question on StackOverflow.