I am developing an UWP app, I am getting an issue with back root frame navigation, I have main page in that I have frame, I navigate all pages into this frame ,, dashboard.xaml, orders.xaml....etc, I my orders.xaml I have another frame...in that frame I navigate 3 forms(xaml pages with a cancel button) when I hit cancel buton in any of those pages, I need to navigate to my orders page back... So I am facing problem with getting main page frame to navigate my Orders.xaml into that,,please help me. Thanks in advance
There are multiple ways to achieve what you want. For example, you can define a public static property in Mainpage that exposes the Frame.
public sealed partial class MainPage : Page
{
public static Frame MainPageFrame;
public MainPage()
{
this.InitializeComponent();
//Frame1 is the name of the Frame in XAML
MainPageFrame = Frame1;
}
...
}
And then in the order details page, use this property to navigate.
MainPage.MainPageFrame?.Navigate(typeof(Orders));
Or you can take advantage of VisualTreeHelper and get the parent Frame i.e "Frame1" like:
//this.Frame gets the Frame holds the order details page (i.e "Frame2")
FindParent<Frame>(this.Frame)?.Navigate(typeof(Orders));
The FindParent method here is a help method uses VisualTreeHelper.GetParent method like the following:
public static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
var parentObject = VisualTreeHelper.GetParent(dependencyObject);
if (parentObject == null) return null;
var parent = parentObject as T;
return parent ?? FindParent<T>(parentObject);
}
This should do it:
Frame.Navigate(typeof(orders));
Related
I have applied ScrollViewer to a user control which automatically scrolls to the bottom if height exceeds.
Now my page is closing having the scrollbar at the bottom position and it remains at the bottom when I reopen the page.
How can I reset the scrollbar to the top every time I open that page.
<ScrollViewer x:Name="myScrollViewer">
<Grid Margin="0,0,0,40">
</Grid>
</ScrollViewer>
ScrollViewer provides the ChangeView method, which can be used to adjust the scrolling state:
// scroll to top
myScrollViewer.ChangeView(0, 0, 1);
You can call this method after the page is loaded to scroll the ScrollViewer to the top.
Update
If you want to access the control on the page in the ViewModel, there are two ways:
1. Public control
This method means that you need to create a public page instance, and then expose the control in XAML, as shown below:
ScrollViewerPage.xaml
<ScrollViewer x:Name="myScrollViewer" x:FieldModifier="public">
<!-- your code -->
</ScrollViewer>
ScrollViewerPage.xaml.cs
public sealed partial class ScrollViewerPage : Page
{
public static ScrollViewerPage Current;
public ScrollViewerPage()
{
this.InitializeComponent();
Current = this;
}
}
After the page is loaded, you can use this code to access the ScrollViewer.
ScrollViewerPage.Current.myScrollViewer.ChangeView(0, 0, 1);
2. Define control variable/property in ViewModel
You can define a variable or property (public) of type ScrollViewer in the ViewModel, and then assign a value to the property when the page loads, and then you can access the ScrollViewer by accessing the property in the ViewModel.
MyViewModel.cs
public class MyViewModel
{
public ScrollViewer MyScrollViewer { get; set; }
// Other code
}
ScrollViewerPage.xaml.cs
public ScrollViewerPage()
{
this.InitializeComponent();
var vm = new MyViewModel();
vm.MyScrollViewer = myScrollViewer;
}
I need to route pages A -> B -> C -> D, once I got into D, I need to use the navigation button back to page D -> A. I am trying to implement this scenario IOS and Android in Xamarin Forms.
Please help
Your case use the Navigation.PopToRootAsync ();
Navigation.PopToRootAsync (); This method pops all but the RootPage off the navigation stack, therefore making the root page of the application the active page.
Navigation.PopAsync (); This causes the Page2Xaml instance to be removed from the navigation stack, with the new topmost page becoming the active page.
The following doc explains well about Xamarin.Forms Navigation.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/hierarchical
Inside the "D" page override the "OnBackButtonPressed" and inside the function iterate trough the pages you no longer need and remove them one by one.
Pseudo code:
protected override bool OnBackButtonPressed()
{
foreach (var page in Navigation.NavigationStack)
{
//find the pages you want to remove
Navigation.RemovePage(PageYouFound);
}
//Set new page
return base.OnBackButtonPressed();
}
You can oveeride OnBackButtonPressed Event and use Navigation.PopToRootAsync
protected override bool OnBackButtonPressed()
{
Navigation.PopToRootAsync();
return base.OnBackButtonPressed();
}
In a Hub view App with subItems Pages, my question is when I navigate to a sub item detail Page and then use command navigate goback, the view always returns to pageroot hub section01.
How can I return the MainHub Page to the original calling section that went to the sub page in the first place?
My research has been fruitless. I don't think snaps are my answer but hey any advice is appreciated.
I apologize if this is a very simple question but...
Thx.
Ok. Thanks for the answers. After looking at this problem for three days I have found a solution but not quite an answer.
this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
By enabling Navigation Caching the page will return to it's sender position. However I still desire to return to the Hub root page to a specific section. If anyone still has info on how to achieve this I would be grateful.
Seasons Greetings.
Well the newbie here has also discovered the MyHub.ScrollToSection(MyHub.Sections[0]);
This allows you to navigate directly to a section thereby bringing it into the current view.
I'm trying to find an answer to the same question. This is what I've found so far. I welcome any better solutions.
Option 1
Enable caching for the page. Note that this must be set in the page constructor or XAML. This will increase memory usage but will improve performance of your app when you navigate back to a cached page.
this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
More information here: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.page.navigationcachemode.aspx
Option 2
Manually save a controls state between page navigations. The example below is using the NavigationHelper class which is added to a new Windows Store project by default.
private void OnNavigationHelperSaveState(obj sender, SaveStateEventArgs e)
{
e.PageState["SelectedSection"] = this.MainHub.SectionsInView;
}
private void OnNavigationHelperLoadState(obj sender, LoadStateEventArgs e)
{
if (e.PageState != null)
{
var sections = e.PageState["SelectedSection"] as IList<HubSection>;
if (sections != null && sections.Any())
{
this.MainHub.ScrollToSection(sections[0]);
}
}
}
More information here: http://msdn.microsoft.com/en-gb/library/windows/apps/hh986968.aspx
you could get the Hub's descendant scrollviewer and register to scrollchanged events, store the scrollOffsets and restore them as soon as the user navigates back to the page by applying the values to the hub's scrollviewer.
I guess you would have to register to the hub's loaded event to get the descending scrollviewer (you can use an Extension method from WinRt XAML Toolkit that allows you to get the descendants by Type (e.g. Scrollviewer)
greetings!
you can delete un back stack with this :
if(this.Frame.CanGoBack)
{
this.Frame.BackStack.RemoveAt(0);
}
Have you tried what i suggested?
Unforunately Hub can't be extended to do this and access it's Scrollviewer so you have to do this with an attached Property or plainly in your page.cs .
First you register an handler for the Loaded event of your hub. In the handler you get the descending scrollviewer (with the help of WINRT XAML Toolkit maybe) and register for it's ViewChanged Event.
You store the paremeters you like somewhere they don't get deleted on page navigation and restore and attach them to the scrollviewer on backwards-navigation.
I can give you example code in the afternoon.
Greetings
It's not a ridiculous request. Try this:
public static class Concurrency
{
public static HubSection GotoSection { get; set; }
}
public class MainPage : Page
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (Concurrency.GotoSection != null)
MainHub.ScrollToSection(Concurrency.GotoSection);
Concurrency.GotoSection = null;
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Concurrency.GotoSection = MainHub.SectionsInView.First();
base.OnNavigatedFrom(e);
}
}
The reason this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; may not be the correct solution is because you might want your hub to be refreshed. If the detail page resulted in an edit (or especially a delete) a back navigation would show stale data, and subject your app to un unexpected state if the user interacts with dead data.
Best of luck!
Enable cache mode on your page at initialization
public MainHubPage()
{
. .......
this.NavigationCacheMode = NavigationCacheMode.Enabled;
.......
}
You need to add Loaded method to Page constructor.
MainHub.Loaded += async (s, e) => await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
//here you can scroll
MainHub.ScrollToSection(Loyaltysection);
});
I need to develop a control which is similar to the Nested Grid in the Smart GWT.
User will be having a column for expansion images, when user clicking on the image in a particular row, a sub grid has to be opened there itself. Here all remaining rows needs to move down.
How can i achieve that functionality? Can anybody give me some clues so that i can proceed.
I have already a grid which is a celltable with custom header(with search functionality implemented).
Thanks,
Saritha.
Create your nested widget (myNestedWidget) that you want to show. It should have a CSS style "position: absolute", unless your grid is added to the LayoutPanel (or similar), in which case you can position your widget directly. Let's call the parent widget of your grid gridParentWidget.
In your CellTable add the following handler:
myTable.addCellPreviewHandler(new Handler<myObject>() {
#Override
public void onCellPreview(CellPreviewEvent<myObject> event) {
if ("click".equals(event.getNativeEvent().getType())) {
if (event.getColumn() == 0) {
int top = myTable.getRowElement(event.getIndex()).getAbsoluteBottom();
int left = myTable.getRowElement(event.getIndex()).getAbsoluteLeft();
myNestedWidget.getElement().getStyle().setTop(top, Unit.PX);
myNestedWidget.getElement().getStyle().setLeft(left, Unit.PX);
gridParentWidget.add(myNestedWidget);
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
int height = myNestedWidget.getOffsetHeight();
myTable.getRowElement(event.getIndex()).getStyle().setHeight(height + "px");
]
});
}
}
});
}
This is obviously an outline of the solution. The details of the implementation may vary slightly depending on which widgets you use for your parent widget and your nested widget. If you change z-indexes somewhere, you have to take it into account too. You also need to make sure that your nested widget fits into the width of your grid, or you'll need to wrap it in a ScrollPanel and set a width to it explicitly.
I'm editing a page in the ToolTwist Designer, and I have all the normal tabs shown - edit page, navpoint, test page, source, etc, but the "Page Data" tab is not showing. How can I make the tab show, so I can enter page data for my page?
The page data tab only appears if there is a widget on your page that requires page data. You also need to editing the navpoint, rather than the page, because the page data belongs to the navpoint, and a single page definition might be shared by many navpoints. In other words, the page data allows widgets to appear different at various locations (navpoints) within the website.
If you are developing a widget that you wish to have use page data, you need to do the following:
In the Widget Controller class, implement the "UsesPageData" interface. This tells the Designer that the page data tab needs to be displayed when you click on a navpoint that references a page that included this widget, and on the tab it creates a section where the XML for this widget can be entered, specific to that particular navpoint.
public class CarouselTab extends WbdWidgetController implements UsesPageData
To give the user an indication of what XML the widget expects, you need to implement a method that returns template XML code. For example:
public XData getInitialPageData(WbdWidget instance)
{
StringBuffer xml = new StringBuffer();
xml.append("\n");
xml.append("\n");
xml.append(" id01\n");
xml.append(" [Label 01]\n");
xml.append(" [Add your widget here 01]\n");
xml.append("\n");
xml.append("\n");
xml.append(" id02\n");
xml.append(" [Label 02]\n");
xml.append(" [Add your widget here 02]\n");
xml.append("\n");
xml.append("");
return new XData(xml);
}
Define a property that defines a name to be displayed above where you enter the XML on the page data tab:
protected void init(WbdWidget instance) throws WbdException
{
instance.defineProperty(new WbdStringProperty("pageDataSection", null, "PageDataSection", ""));
...
}
Use the page data when you are generating the page:
#Override
public void renderForJSP(WbdGenerator generator, WbdWidget instance, UimHelper ud, WbdRenderHelper rh) throws WbdException
{
...
Xpc xpc = ud.getXpc();
xpc.start("tooltwist.wbd.getPagedata", "select");
xpc.attrib("navpointId", WbdSession.getNavpointId(ud.getCredentials()));
xpc.attrib("pageDataSection", pageDataSection);
XData pagedata = xpc.run();
// Do something with the page data
...
}