Using NavigationService.RemoveBackEntry() I can remove one entry from the navigation stack. Is there a convenient way to remove all back navigation items in my app (scenario: I have a sign-up procedure which consists of multiple pages, and after successful registration I do not want the user to navigate back to the registration steps).
It's not that inconvenient to do that with RemoveBackEntry:
while(NavigationService.CanGoBack)
{
NavigationService.RemoveBackEntry();
}
Or use this, a single line code
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
while (NavigationService.RemoveBackEntry() != null) ;
}
Related
I have the following page navigation in my app:
AnyPage -> Login -> Register
When the user gets registered he is automatically logged to. So I want the Login page to be closed automatically if the user go back to it and is logged.
I tried to add some code to the LoginPage.onNavigatedTo method but it doesn't work.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
if(AccountController.isLogged()){
Frame.GoBack();
}
}
How can I do it?
The OnNavigatedTo and OnNavigatedFrom methods are part of the ongoing navigation operation. When you try to start a new navigation while there is one in progress, navigation methods will stop and return false.
Simple trick is: Make your OnNavigatedTo async and add a delay before navigating back.
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
if(AccountController.isLogged()){
await Task.Delay(1);
Frame.GoBack();
}
}
The reason this works is: Navigation is handled on the UI Thread. As the Event Methods are void returning, they are not awaited and if you return a task inside of them, the current caller finishes his current task. Whatever comes after the await is queued to the Dispatcher and finished once he has time for it (which is immediately after the navigation operation finishes).
I've got a Flyout embedded within an AppBarButton like so:
<AppBarButton x:Name="appbarbtnOpenPhotosets" Icon="OpenFile" Label="Open Existing Photoset[s]" AutomationProperties.Name="Open File" Tapped="appbarbtnOpenPhotosets_Tapped" >
<Button.Flyout>
. . .
</Button.Flyout>
</AppBarButton>
I want to, under certain circumstances, first present the user with an opportunity to rename a file prior to seeing the Flyout. I tried seeing if that would work like this:
async private void appbarbtnOpenPhotosets_Tapped(object sender, TappedRoutedEventArgs args)
{
// Want to conditionally postpone the operation
bool myBucketsGotAHoleInIt = PhotraxUtils.GetLocalSetting(CAINT_BUY_NO_BEER);
if (myBucketsGotAHoleInIt)
{
MessageDialog dlgDone = new MessageDialog("Can you see me now?");
await dlgDone.ShowAsync();
args.Handled = false; // <= adding this made no difference
}
}
This works, in that I see the "Can you see me now?" dialog, but that prevents the Flyout from flying out. A Flyout that doesn't fly out is no more useful than a flying squirrel or fish that doesn't motate through the air.
So how can I temporarily suppress my flyout but then call it forth? The Flyout does not have an Open() method...Is there some other way to invoke it?
Flyouts attached to Buttons open automatically when you click the control.
If you don't want it to open automatically, you need to attach it to another control.
Example taken from official documentation:
<!-- Flyout declared inline on a FrameworkElement -->
<TextBlock>
<FlyoutBase.AttachedFlyout>
<Flyout>
<!-- Flyout content -->
</Flyout>
</FlyoutBase.AttachedFlyout>
</TextBlock>
Then you can show the Flyout whenever you want, calling FlayoutBase.ShowAttachedFlyout() and passing the FrameworkElement casted value of your control.
FlyoutBase.ShowAttachedFlyout(frameworkElement);
So, in your case:
async private void appbarbtnOpenPhotosets_Tapped(object sender, TappedRoutedEventArgs args)
{
// Want to conditionally postpone the operation
bool myBucketsGotAHoleInIt = PhotraxUtils.GetLocalSetting(CAINT_BUY_NO_BEER);
if (myBucketsGotAHoleInIt)
{
MessageDialog dlgDone = new MessageDialog("Can you see me now?");
await dlgDone.ShowAsync();
// New code
FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}
}
If you can't change the control, you should able to use the code I posted with Buttoninstead of TextBlock. I'm not sure about this, but you can try.
I am developing a Login screen in which the user needs to introduce their data and then submit them.
Considerations which I had: I have thought about using a Page, but eventually I rejected the idea because if I put Login page before the MainPage, then if I go back from MainPage, then it would go to Login page, which is not what I want. And if Login page were after MainPage, then if I execute for instance the app for first time, without being logged in, if I press back, then it would go to MainPage which I don't want as well.
The problem: I decided finally to use a Popup. At the moment looks perfect, but when I want to use a textbox, the Keyboard overlaps that textbox, and what I want is to move the Popup upwards just like a normal page. I don't know if is that possible, otherwise I am willing to hear some alternatives.
Thank you in advance.
In WMAppManifest.xml remove the property of Navigation Page and in you App.xaml.cs you have something like:
private void Application_Launching(object sender, LaunchingEventArgs e)
{
LoadDefautPage();
}
void LoadDefautPage()
{
if (StartForFirstTime)//tombstone local variable
{
if (!IsLoggedIn)//flag save it in IsolatedStorageSettings
{
RootFrame.Navigate(new Uri("/LoginPage.xaml", UriKind.Relative));
}
else
{
RootFrame.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
StartForFirstTime = false;
}
}
finally remove Back Entry in MainPage:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
while (this.NavigationService.CanGoBack)
{
this.NavigationService.RemoveBackEntry();
}
}
It's just an idea, let me know how it goes (:
I have an application with a popup menu. I'd like to use the popup in the usual way (i.e., it should appear when the user right-clicks anywhere in the window), but I'd also like to attach it to the main MenuBar at the top of the window. I'm not sure how to do this.
I'd thought it would as simple as calling
myJMenuBar.add(myPopupMenu)
but this doesn't work.
JMenuBar.add() wants a JMenu parameter, not a JPopupMenu.
Does anyone have any suggestions?
Instead of trying to reuse the JPopupMenu object, the best approach would be to encapsulate the actions that the menus perform, and reuse those. The popup would trigger those actions, as would the menu items.
From the Action JavaDoc:
In addition to the actionPerformed method defined by the ActionListener interface, this interface allows the application to define, in a single place:
One or more text strings that describe the function. These strings can be used, for example, to display the flyover text for a button or to set the text in a menu item.
One or more icons that depict the function. These icons can be used for the images in a menu control, or for composite entries in a more sophisticated user interface.
The enabled/disabled state of the functionality. Instead of having to separately disable the menu item and the toolbar button, the application can disable the function that implements this interface. All components which are registered as listeners for the state change then know to disable event generation for that item and to modify the display accordingly.
and
JPopupMenu, JToolBar and JMenu all provide convenience methods for creating a component and setting the Action on the corresponding component. Refer to each of these classes for more information.
I had the same issue. A right-mouse-click as well as a top menu with exactly the same (complicated) set of menu items. The 'Action' class is something to consider if you are talking about enablement choices, but it's not dealing with visibility and in my case there was also a dynamic list of entries based on a current selection that I wanted to reuse.
So I ended up implementing a 'Bridge' design pattern (I think) for the methods I actually use (add() and addSeparator()):
public static class MenuBridge
{
private JPopupMenu popupMenu;
private JMenu menu;
public MenuBridge(JPopupMenu popupMenu)
{
this.popupMenu = popupMenu;
}
public MenuBridge(JMenu menu)
{
this.menu = menu;
}
public void addSeparator()
{
if(popupMenu!=null) popupMenu.addSeparator();
else menu.addSeparator();
}
public void add(JMenuItem item)
{
if(popupMenu!=null) popupMenu.add(item);
else menu.add(item);
}
}
So then I can write a reusable method that computes the menu items and synchronize my right mouse click with the top-level menu:
public void addTaskMenuItems(DefaultMenu menu, List<MDProcTask> taskList)
{
...
menu.add()/menu.addSeparator()
...
}
addTaskMenuItems(new DefaultMenu(popupMenu),taskList);
...
taskMenu.addMenuListener( new MenuListener() {
public void menuCanceled(MenuEvent menuevent)
{
}
public void menuDeselected(MenuEvent menuevent)
{
}
public void menuSelected(MenuEvent menuevent)
{
taskMenu.removeAll();
addTaskMenuItems( new DefaultMenu(taskMenu),getSelectedTasks());
taskMenu.revalidate();
}});
When I go to parse through the table, all the stuff I created programmatically is missing...
I must be forgetting something so that it's losing all the stuff that I built programmatically (I am only getting the shell of the table).
Any ideas?
If I put the table in a Session object after I programmatically create it then it works except all the values the user enters will not be there obviously.
protected void btnSave_Click(object sender, EventArgs e)
{
SaveMainGrid(tblCC);
// SaveMainGrid((System.Web.UI.WebControls.Table)Session["tblMain"]);
}
private void SaveMainGrid(Control control)
{
foreach (Control ctrl in control.Controls)
{
if (ctrl is RadNumericTextBox)
{
RadNumericTextBox t = ctrl as RadNumericTextBox;
}
else
{
if (ctrl.Controls.Count > 0)
{
SaveMainGrid(ctrl);
}
}
}
}
This is likely another case of asp.net lifecycle. If you dynamically create controls, they aren't going to be available in the viewstate unless you recreate them. Even then, I don't know that the values would be persisted.
(I think they might. It's been a while since I fought this particular Web Forms quark.)
Check this question out for more info.
Why are you creating the table dynamically? Can you use an asp:GridView?