Prism RegionManager: how to navigate from a current view? - c#

In order to load a Prism Module's view to a WPF application Region
<ContentControl Name="MainRegion" prism:RegionManager.RegionName="MainRegion"/>
I can use regionManager.RequestNavigate:
this.regionManager.RequestNavigate(RegionNames.MainContentRegion, toViewUri);
Sometimes I need to just remove the Module's view from the MainRegion (clear everything). If I do it by this.MainRegion.Content = null; then all is okay, except I cannot navigate to the previous view until I navigate to some other one.
How to correctly navigate from a current view without navigating to any other view?

Have you tried either of these?
regionManager.Regions[RegionNames.MainContentRegion].Remove(view)
regionManager.Regions[RegionNames.MainContentRegion].Deactivate(view)

IRegion.Remove does exactly that.

Related

Navigation between pages in Xamarin Forms

I have the following command inside a VM:
ICommand LaunchGameCommand => new Command(() =>
{
//Navigation.PushAsync(...
});
According to the answers here I should be able to use something akin to the navigation in the commented code; however, the Navigation object seems to reside in Android.Content.Res... which seems to be something else entirely.
Is this still the correct method of navigating between views / viewmodels in Xamarin Forms, or has this now been superseded with an alternate method?
Navigation is part of a page, you can’t find navigation property if you don’t have the reference to a some page, you need to have access to your current page in your view model to see this property, you can have access to your current page using
Application.Current.MainPage.Navigation.Push...
Are you using any particular MVVM framework? Most of these include a way of navigating from VM to VM.
I use FreshMvvm. It allows you to perform the following to navigate between VMs and also pass data:
CoreMethods.PushPageModel<MyNextPageModel>(DataToPass);
More details here

Deep linking/Navigating to tabbed page in prism not working

I have a master detail page as the root page for my application. As a detail page for that I have a tabbed page. In the tabbed page I have a content page and a navigation page containing one content page. In the master detail's OnNavigatedTo I'm retrieving some organisation data from the cloud and then I want to navigate to a manage organisation page which is the plain content page in the tabbed page.
Using NavigateAsync and a relative uri to the manage organisation page I find that the Tabbed Page OnNavigatedTo is hit twice and then I get an exception such as (simplified) below. I can also see Binding errors in my output showing that elements on my manage organisation page xaml tried to bind to the tabbed page view model.
I'm not sure if this is an issue with the view model auto wire change in 6.2 or if it's a deep linking issue or if I've done something wrong.
"Sequence contains no elements".
at System.Linq.Enumerable.Last[TSource] (IEnumerable`1 source) [0x00079]
at Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnAttachedToWindow () [0x00011]
in C:\BuildAgent\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\AppCompat\NavigationPageRenderer.cs:189
Using XF 2.3.1.114, Prism.Forms 6.2, I'm not sure if other packages are relevant. If you think so I can include them.
Also interestingly, it works if I try navigate to the content page in the navigation page from the master detail i.e. "TabbedPage/NavigationPage/ContentPage".
Any ideas what the problem might be?
So first thing first, you don't have the proper XAML syntax for your TabbedPage. When defining the default page for a NavigationPage in XAML you must supply the page via the Arguments element:
<views:SimpleNavPage Title="Foo">
<x:Arguments>
<views:NestedContentPage />
</x:Arguments>
</views:SimpleNavPage>
You must also have the proper ctor in your navigation page:
public SimpleNavPage(Page root) : base (root)
{
InitializeComponent();
}
Now, I personally don't recommend navigating within the OnNavigatedTo unless you can absolutely guarantee that you will not be adding that page in another deep link, or navigation scenario. Imagine you start out with NavigateAsync("MainPage") and that has an OnNavigatedTo that does a deep link navigation operation. Now you decide to NavigateAsync("SomeOtherPage") in which it NavigateAsyc("AnotherPage/MainPage/SomeOtherPage/LastPage") from within it's OnNavigatedTo. Now, you will have created an issue because the MainPage.OnNavigatedTO will have kicked off another navigation operation while you are still navigating to the next "SomeOtherPage". You are asking for trouble.

Using single View for multiple ViewModels with Caliburn.Micro on Windows Phone 8.1

I have a Windows Phone 8.1 app using Caliburn.Micro. In the app I have a few ViewModels that fetch data in different way and with different logic but show them in the same way. So I want to make all those ViewModel use the same one View.
I found out that ViewLocator.LocateTypeForModelType is a method that gets executed for mapping ViewModels to Views. So I override it to use my custom attribute when present:
var original = ViewLocator.LocateTypeForModelType;
ViewLocator.LocateTypeForModelType = (modelType, displayLocation, context) =>
{
var useViewAttributes = modelType.GetTypeInfo().GetCustomAttributes<UseViewAttribute>(true);
if (useViewAttributes.Count() == 1)
{
var viewTypeName = string.Concat(modelType.Namespace.Replace("Model", string.Empty), ".", useViewAttributes.First().ViewName);
var type = AssemblySource.FindTypeByNames(new List<string>() { viewTypeName });
return type;
}
return original(modelType, displayLocation, context);
};
Stepping through the it seems to work fine. If I navigate to a ViewModel and that ViewModel has a UseView, my method returs the correct View.
The app navigates to the correct View but the ViewModel is never created. Kind of like Caliburn.Micro forgot about the ViewModel, or was looking for one using a different convention, or something.
I found out that ViewModelLocator.LocateTypeForViewType is called after navigation to a View to resolve the ViewModel. The ViewModel type from the previous step seems to be forgotten completely.
In ViewModelLocator.LocateTypeForViewType I only have access to the View type and I do not know, how to make it resolve the correct ViewModel from the previous step. I could scan all the ViewModel and find the ones with the correct attribute, but I would not know which one to choose.
Any ideas on how to approach this?
Here is a minimal project showing my setup: https://dl.dropboxusercontent.com/u/73642/CMVMTest.zip
This sort of solution would work everywhere else except for the top level navigation. The reason for this is there is sort of a "double dispatch: going on when you navigate.
As you know the Frame or PhoneNavigationFrame control (depending on WinRT or Silverlight) is view based in it's navigation. So the steps look a little like this.
Your code tells the navigation servie=ce to navigate to ProductViewModel.
It uses ViewLocator (where you've injected your code) to locate ProductView and tells the Frame to navigate to that.
The navigation service then responds to the navigating event to ProductView and locates the correct view model using ViewModelLocator.
It then instantiates and binds this view model.
This sort of view model to view to view model step in navigation service causes the hiccup in your code.
You should be able to create dummy views that simply inherit the base view and add nothing. So if you have MySharedView.xaml then declaring what's below should be enough.
public class SecondView : MySharedView { }
It's not ideal I know, but does get you the reuse you're after. Having the navigation service remember the view model between the navigating and navigated events becomes complicated with all the external factors that can cause navigation as well.

Changing Views in Fragments

In My app, i use an altered Example of the ViewPagerIndicator, which launches 5 Fragments. so far all works well, but the fragments do have to change their View (completly new layout) for other purposes. how do i do that? a Fragment doesn't have a function SetContentView like activities do. so is there a way to update the view or something like that?
Use Fragment.getView() to get the root view of the Fragment. On that View, call removeAllViews(). Then build your new views and add them to the view you got from getView().
Edit
I never used Mono for Android before, but looking at the documentation; I suggest you put the inflated View from inflater.Inflate in a private member of your Fragment. Later on, when needed, you can use that reference to edit your layout.

How to send data to a page navigated to through the Frame.Navigate in Silverlight 4

Platform:
Silverlight 4 / .NET 4
Background:
I have a page that consists of two parts. The left part is a tree view, the right one is the content area. When I select a tree item, an appropriate UserControl page should be loaded in the right part of the page, depending on the type of the tree item.
I am using a Frame object, defined in XAML.
When a user selects a tree view item, I resolve the item's type and then I navigate to the page defined for that type.
However, Frame.Navigate is an asynchronous method so if I try to get the frame's content after Navigate, the frame has not navigated yet, so I either get nothing or the last loaded page.
contentFrame.Navigate(new Uri("/PageA.xaml", UriKind.Relative));
PageA page = contentFrame.Content as PageA;
// page here is either null or a previously opened page
Problem:
I need to send some data (stored in treeview item's Tag) to the page being navigated to and the only Frame.Navigate overload is asynchronous (without callback). How can I send some data to the navigated page? Is there any other technique for accomplishing what I need?
You can use the NavigationService provided by Silverlight. It has query string support using which you can build RESTful URI. I am assuming that you need to pass some context based data to the landing page. Following links might help you
http://www.silverlightshow.net/items/The-Silverlight-3-Navigation-Framework.aspx
http://blogs.microsoft.co.il/blogs/alex_golesh/archive/2009/04/02/silverlight-3-quick-tip-6-navigation-framework-and-uri-routing.aspx
http://www.wintellect.com/CS/blogs/jprosise/archive/2009/04/07/silverlight-3-s-new-navigation-framework.aspx
Although the links says Silverlight 3, these features are supported in Silverlight 4 as well.
You definitely want to use some flavor of the M-V-VM pattern that Nilesh suggested.
I guess you could also have a static class that holds static references of objects.
You can simply refer to static objects here when your frames have completed their event (e.g. NavigatedTo).

Categories

Resources