I have the following set in my view code behind
NavigationPage.SetHasNavigationBar(this, false);
and I have it also in the XAML
NavigationPage.HasNavigationBar="False"
However the navigation panel is still displaying when navigating with Prism and the follow code:
await NavigationService.NavigateAsync("NavigationPage/RecipeListPage");
Navigating with the absolute method such as:
NavigationService.NavigateAsync(new System.Uri("http://www.RecipeDatabase/RecipeListPage", System.UriKind.Absolute));
Fixes this issue. Not sure why its needed. Also hiding with just the XAML code as well is sufficient.
Enjoy.
Related
I'm epxloring different ways to best show dialog windows in my application.
MahApp Metro's IDialogCoordinator seems quite useful, but I couldn't quite adjust it to my use case yet.
Say I'm creating a UserControl (view), whose ViewModel needs to be able to display dialogues.
These dialogues should, when displayed, overlay/span the UserControl only, NOT the entire Window in which the UserControl is hosted.
Is there any way to achieve this?
Default behavior always seems to span over the entire window, and I haven't found any way to change this yet.
So far, I've been using the Dialog coordinator in a very straightforward way, doing the following in my view:
<UserControl
xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
Dialog:DialogParticipation.Register="{Binding}">
and set set the instance in my view's constructor by,
viewModel.Initialize(DialogCoordinator.Instance);
which I'd then call in the viewmodel via
IDialogCoordinator _DialogCoordinator; // set with viewModel.Initialize() called from the view
private async Task _SomeCmdExecute()
{
await _DialogCoordinator.ShowMessageAsync(this, "HEADER", "TEST");
}
Thanks!
Dialogs in MahApps.Metro are always at the window level (see the container PART_MetroActiveDialogContainer in the window's style.)
What you can do is changing the styling of dialogs, so they don't stretch horizontally accross the entire window. See the default template MetroDialogTemplate for reference.
I have problem how to implement sub-page navigation in UWP. The page is in RootFrame, which I can use on navigation. But i want to use something like this:
<Page>
<Grid>
<Frame x:Name="MyFrame"/>
</Grid>
</Page>
What I want is, use Navigate method of control MyFrame in ViewModel. I can call the method from code-behind, but I'm developing my app using MVVM. I'm not sure, if Template10 can work with sub-frames.
I appreciate any advice.
EDIT:
More details:
I have pivot control which is in page. the pivot has 2 tabs (pivotitems). The content of the pivotitem must be navigable. What I mean: I pivotitem 1, I need to have one Frame and use it for navigation in the pivotitem. My problem is, how to use or how to call the frame in pivotitem from ViewModel, especially I need to call Navigate method. Now I'm using Template10's navigation service and it's working with rootframe. I don't know, how to use it for other let's say sub-frames.
You can always do this.
var nav = Bootstrapper.NavigationServiceFactory(BackButton.Attach, ExistingContent.Exclude, this.Frame);
This will give you a navigation service for the frame in your page. You can then use session state, if you like.
Bootstapper.SessionState["MyNav"] = nav;
From here your view-model can access the service and navigate. You can repeat this for as many frames as you have. And you can then handle navigation in your view-model without consideration of "where" the frame is, just that your logic requires it to nav.
Does this make sense?
I don't know how you are going to trigger the navigation change so I'll assume it will start from a button click. I am also assuming the button's Command property is already bound to an ICommand in the viewmodel (the same concepts can be applied to different kinds of views).
All we have to do now is to make the ICommand implementation call our custom NavigationService to perform the content switch. This NavigationService class will be nothing but a simple proxy to the window global frame. Its main navigation method can be as simples as:
public void Switch()
{
var rootFrame = Window.Current.Content as Frame;
if ((rootFrame.Content as ParentPage) != null)
{
rootFrame.Navigate(typeof(ChildPage));
}
}
So you have tagged this with Template10 but it seems to be a more general question for UWP as a whole. I wonder if you have considered all of the inherent complexities with this approach - specifically related to suspension and resume. For each frame you have, you would need to save and restore navigation state, which isn't straight-forward when you have nested frames. Have you also considered how global navigation would work?
Template 10 does support the concept of multiple NavigationServices and, therefore, multiple frames, but only from the perspective of you can create them. Template10 does not inherently understand how such frames may be related to each other, so cannot perform automatic back propagation where you have something like:
FrameA[Main->Page1->Page1:Pivot1.FrameB[View1->View2->View3]]
Here we have two frames - FrameA and FrameB. FrameA has navigated from
Main to Page1. Page1 has a Pivot that hosts FrameB in PivotItem1 and
FrameB has navigated from View1 to View 2 and from View2 to View 3.
Global navigation (i.e. the shell back, etc.) would be automatically wired to FrameA, so you would need to intercept that action, and then handle you own navigation activity for FrameB.
Take a look at the BackButtonBehavior to see how it is possible to intercept the global back and then put in place your own action.
I don't know if you can do something like that..
One possible workaround is to use a Messenger that sends a message from your viewmodel to the view's code behind.. I'm not a fan of this solution though, because as I said before you have to use the page's code behind..
I want to change the icons and what they do in code in my WP7 application. I've tried in the MainPage constructor and in the MainPage_Loaded but it says ApplicationBar (x:Name) is null all the time.
How can I change it since I use same page and different states?
Unfortunately the application bar buttons are not accessible via code at the moment. I followed one of the examples of the official Mircosoft Training Kit for WP7 to accomplish that task. Here is the XAML and some code:
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar>
<shell:ApplicationBarIconButton IconUri="/icons/appbar.pin.png" IsEnabled="True" Text="Anpinnen" x:Name="appPinPage" Click="appPinPage_Click" />
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
Please note that ApplicationBar is a property of PhoneApplicationPage so that you do not have to give an explicit name to the ApplicationBar object that you assign to the ApplicationBar property of the PhoneApplicationPage. Here is an example of changing the picture of the button in the xaml code above. That code is called in the overridden OnNavigatedTo() method of the PhoneApplicationPage.
if (this.ViewModel.IsPinned())
{
((ApplicationBarIconButton)this.ApplicationBar.Buttons[0]).Text = Resource1.txtUnpin;
((ApplicationBarIconButton)this.ApplicationBar.Buttons[0]).IconUri = new Uri("/icons/appbar.unpin.png", UriKind.Relative);
}
else
{
((ApplicationBarIconButton)this.ApplicationBar.Buttons[0]).Text = Resource1.txtPin;
((ApplicationBarIconButton)this.ApplicationBar.Buttons[0]).IconUri = new Uri("/icons/appbar.pin.png", UriKind.Relative);
}
Try removing the x:Name property and access it using Page.ApplicationBar.
Unfortunately, the ApplicationBar isn't a Silverlight control (doesn't inherit from UIElement); what that means is that it can't be accessed with a x:Name neither the buttons inside it, but you can access it inside the page using the ApplicationBar property!
Check this sample to see how you can create and access the ApplicationBar from the code behind of a page.
If you are willing to go with an MVVM architecture, you should check the ApplicationBarBehaviour from the Cimbalino Windows Phone Toolkit, it will save you a lot of work!!!
I was working on a WPF project today that had a main nav window and then 4 pages that were loaded within this main window (using NavigationService.Nagivate...).. Within the XAML this created a lot of duplicate code so I wanted to refactor the menu into a user control that I could then bind to each page. I tried to create a class to handle the navigation and loading of each page but I discovered that NavigationServices is a sealed class and cannot be instantiated.
Would anyone please provide a suggestion/solution on how to create a usercontrol with a menu item that will allow the ability to navigate to new pages within the project. I have been able to do this within pages and the direct code behind but I have not had any luck trying to separate the two. If this is too vague please let me know and I will provide more deails with code samples.
Thanks in advance
Create a NavigationService dependency property on your user control. Then, when you instantiate your control, bind this property to the NavigationService of the container where the navigation should occur. For example, a page might display the user control like this:
<local:NavBox NavigationService="{Binding NavigationService, RelativeSource={RelativeSource AncestorType={x:Type NavigationWindow}}}" />
Now when your UserControl calls Navigate on its NavigationService, that will effectively call Navigate on the containing NavigationWindow's NavigationService. (This can be modified in the obvious way to support Frame or Page instead of NavigationWindow.)
I need some help with overlaying views using the prism framework.Its a little more complexed than that so let me explain.I could be over-thinking this as well :D
i have shell (wpf window) and i have 2 views(A & B - both usercontrols) in a module.
when the shell loads it loads view A. On view A i have a button to "popup" view B
for some user input. so naturally i would think to some sort of modal window/control, maybe even a popup. however the problem i face with the popup is that when i move the shell the popup remains fixed and it doesnt block events in view A. I've tried disabling view A to stop events being fired and i've also tried to use a to get the view B move with the shell. Only the canvas works but i now need a way to block it tho'. Is there anyway i can overlay a view on top of another view with prism? or how does everyone else create modal popups with prism & wpf? any advise or pointers would be greatly appreciated.
If you want to use embedded dialogs without an extra window, you can use Prism's RegionManager to achieve the outlined behavior. The trick is to put the PopUp region parallel to your main region in the visual tree:
<Grid>
<ContentControl cal:RegionManager.RegionName="MainRegion" IsEnabled={Binding IsNoPopUpActive} />
<ContentControl cal:RegionManager.RegionName="PopUpRegion"/>
</Grid>
Now use the RegionManager to put view "A" into the "MainRegion". Create a controller class similar to IPopUpDialogController. It should be responsible for putting your view "B" (or any other PopUpView in your application) into the "PopUpRegion" on demand. Addtionally, it should control a flag that signal the underlying "MainRegion" to be enabled or disabled. This way a user won't be able to play with the controls in your view "A" until the pop up is closed.
This can even be done in a modal fashion by using ComponentDispatcher.PushModal() before pushing a frame onto the Dispatcher. However, I would recommend avoid modal dialogs.
Update: As requested in a comment, the IsNoPopUpActive could be implemented in the backing view model. There you could link it to RegionManager's View collection for the popup region:
public bool IsNoPopUpActive
{
get { return _regionManager.Regions["PopUpRegion"].Views.Count() == 0; }
}
Remember to trigger a PropertyChanged event as soon as you modify the views collection (add/remove a popup).
Just for your information: nowadays I avoid disabling the controls in the background and instead insert a transparent panel. This avoids clicking on background controls. However, this does not handle keyboard input (tab-ing to controls). To fix the keyboard input you need to make sure that the keyboard focus is trapped in the popup (MSDN on WPF Focus concepts).
Adding the following focus attributes to the popup region should do the trick:
KeyboardNavigation.DirectionalNavigation="None"
KeyboardNavigation.ControlTabNavigation="None"
KeyboardNavigation.TabNavigation="Cycle"
KeyboardNavigation.TabIndex="-1"
If you are using WPF + MVVM with Prism you can take a look at this Message View overlay controller. The nice part about this approach is you can write unit tests on you view model using a mock overlay controller and have the mock controller return the result that the user would choose in the overlay.
You can find it here: http://presentationlayer.wordpress.com/2011/05/24/wpf-overlay-message-view-controller/
Hope this helps