Different Navigation Types Between Pages - c#

I am trying to make an app with a Main Page that is a plain Content Page (i.e. no toolbar) which has a button that leads into a Navigation Page (with toolbar). I'm struggling to find any resources to help me out in this specific case.
I have tried the following. In my App.xaml:
public partial class App : Application
{
public App ()
{
InitializeComponent();
MainPage = new App5.MainPage();
Pallets = new NavigationPage(new Pallets()); //Error: 'Pallets' is a type but is used like a variable
}
...
}
Above is the error I get on Pallets. I could change Pallets for MainPage and write the whole app with Navigation pages, which I will do for now, but I would prefer not to.
In my MainPage.xaml.cs, I'm trying to switch the view when the button is clicked:
public partial class MainPage : ContentPage
{
...
async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new Pallets());
}
}
I have seen examples such as this that include Navigation Page to Navigation Page buttons, but not plain Content Page to Navigation Page buttons.

Related

Selenium Page Object Model: Best way to handle Return Pages for Modals

I'm currently working on the POM of a web app, that allows to open modals from the navigation bar. The navigation bar stays the same for every page you're on. Each modal can be opened from every page.
I have defined a page object for each modal. Also the navigation bar is a pageobject,
What would be the best way to return to the page, that the modal was opened from?
So for example, you are on the Page FooPage and open modal AboutModal. What is the best way to return to FooPage? It should also work for BarPage and other Pages.
My first approach was, that i define a BasePage Object, which only includes the webdriver and navigationbar. i extend every Page on the web app from this BasePage. Then i could do something like this:
Code for FooPage:
public class FooPage: BasePage
{
private NavigationBar NavBar;
public FooPage(IWebDriver driver): base(driver)
{
...
this.NavBar = new NavigationBar(driver);
}
public NavigationBar Navigate()
{
return NavBar;
}
...
}
public class NavigationBar
{
...
public openAboutModal(BasePage currentPage)
{
log.Info("Open About Modal");
Action.Click(NavigationBarElements.AboutButton);
return new AboutModal(Driver, currentPage);
}
}
public class AboutModal
{
...
protected BasePage ReturnPage;
public AboutModal(IWebDriver driver, BasePage returnPage)
{
...
this.ReturnPage = returnPage;
}
public BasePage CloseAboutModal()
{
return this.ReturnPage;
}
...
}
This is not practical and not intuitive, because we have to remember on which pageobject we currently are, when writing tests. Also only the methods from BasePage are available, which means we have to additionaly navigate back to the page we wanted to be on.
So instead of writing
public class ModalTests
{
[Test]
public void CheckAboutModal()
{
Login() // FooPage
.Navigate() //NavigationBar
.openAboutModal() // AboutModal
.doSomeStuff() //AboutModal
.CloseAboutModal(); //FooPage
}
}
we have to do
public void CheckAboutModal()
{
Login() // FooPage
.Navigate() //NavigationBar
.openAboutModal(new FooPage(Driver)) // AboutModal
.doSomeStuff() // AboutModal
.CloseAboutModal() // BasePage
.Navigate() //NavigationBar
.ToFooPage(); // FooPage
}
}
How can I return to the calling Page of the modal, without making Testwriting to complicated?
Rather than write your test as one giant method-chaining call, use variables whenever you need to refer back to a certain page model. Your test can simply become:
var foo = Login();
foo.Navigate()
.openAboutModal()
.doSomeStuff()
.CloseAboutModal();
// Continue your test after closing the modal
foo.SomeOtherOperation();
In cases like this, the modal doesn't need to return anything. The CloseAboutModal() method can be a void return type. Your test should understand the larger context in which the modal is being used, and create local variables appropriately in order to "return" back to the main page.

Close a modal page via NavigationService

In my Xamarin.Forms app I have a Navigation Service (based on Mastering Xamarin.Forms), and I now want to Push and Pop Modal Pages.
So I adopted the NavigateTo function from
public async Task NavigateTo<TVM, TParameter>(TParameter parameter) where TVM : BaseViewModel
{
await NavigateToView(typeof(TVM));
if (XamarinFormsNav.NavigationStack.Last().BindingContext is BaseViewModel<TParameter>)
{
((BaseViewModel<TParameter>)XamarinFormsNav.NavigationStack.Last().BindingContext).Init(parameter);
}
}
into a new one for Modal Pages
public async Task NavigateToModal<TVM, TParameter>(TParameter parameter) where TVM : BaseViewModel
{
await NavigateToViewModal(typeof(TVM));
if (XamarinFormsNav.ModalStack.Last().BindingContext is BaseViewModel<TParameter>)
{
((BaseViewModel<TParameter>)XamarinFormsNav.ModalStack.Last().BindingContext).Init(parameter);
}
}
The Modal Page is a login form called from StartPageViewModel when no login credentials can be found
await NavService.NavigateToModal<LoginPageViewModel, LoginData>(loginData);
Page and ViewModel appear and work as expected. But it does not disappear.
The NavigationService method is
public void RemoveModalView()
{
XamarinFormsNav.PopModalAsync(true);
}
But nothing happens, the I get the same result when I call PopModalAsync from the ViewModel of the Page.
How can I properly close a Modal Page?
Thank you!

TabbedPage - Call method when certain Tab is active

I have a scenario where I want to call a method when the user of the app navigates to a certain tab of the TabbedPage.
Example: If I navigate to tab no. 3 of my TabbedPage, a certain method shall be called.
How do I achieve that?
By default all tabs of the TabbedPage are loaded when I start the app.
I am writing in Xamarin - C#.
Best regards!
There are two sample ways to achieve that.
One is using OnAppearing method inside the needed item of tab page.
For example, the tab no. 3 of TabbedPage is ItemsPage, then its ItemsPage.xaml.cs code as follows:
public partial class ItemsPage : ContentPage
{
public ItemsPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
// Call your needed method here
}
}
The another way is using OnCurrentPageChanged methond inside the tabbedpage.xaml.cs.
For example, the code as follows:
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnCurrentPageChanged()
{
base.OnCurrentPageChanged();
if(CurrentPage.Title == "tab no. 3 title")
{
// call your needed method
}
//Console.WriteLine(CurrentPage.Title);
}
}

Growing memory allocation as WPF application navigates

I am building a WPF application and have been trying to implement opening a new page when a button is clicked.
The button is in the page MainPage and it opens the page SafetySettings. There is then a button in the SafetySettings page which opens the MainPage.
The only way I have been able to open the pages successfully is with the following:
private void btnTest_Click(object sender, RoutedEventArgs e)
{
SafetySettings safety = new SafetySettings();
this.Frame.Navigate(typeof(SafetySettings),safety);
}
This works as desired but I noticed the memory allocation of the program continuously increases as I swap between the pages. I think I am not implementing this correctly but I could not figure out another way to open a new page from the current page.
MainPage.xaml.cs
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace DataAcquisitionGUI
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void btnTest_Click(object sender, RoutedEventArgs e)
{
SafetySettings safety = new SafetySettings();
this.Frame.Content = null;
this.Frame.Navigate(typeof(SafetySettings),safety);
}
}
}
Your memory allocation is growing cause you create SafetySettings new each time you click the button and I think you do not dispose the item correctly so there is no clean-up.
Implement the IDisposable interface in your SafetySettings or create a method which "destroys" the instance of your class. This helps you to keep your application clean of unused resources!

Custom Page Class w/ automated unload Event

we have a rather large Silverlight application and we need to add some extra functionality to it.
The App consists of an Frame-Element and a TreeView w/ HyperlinkButtons for the navigation. Every content which will be loaded into the main Frame is a Page.
Now, I need to hook into every Page's unload event. Currently we use something like this:
/* PageX.xaml */
<navigation:Page
x:Class="Foo.Views.PageX"
<!-- namespacing -->
Title="Test Page X"
Unloaded="Page_Unloaded">
...
</navigation:Page>
Code-behind:
/* PageX.xaml.cs */
/* usings */
namespace Foo.Views
{
public partial class PageX : Page
{
public PageX() {
InitializeComponent();
}
private void Page_Unloaded(object sender, RoutedEventArgs e) {
/* CODE */
}
}
}
This approach need to be implemented on each and every Page, as the code within the unloaded method stays exactly the same... As I mentioned earlier, we have a couple of Pages and it would be much more useful to create a custom Page-class where this Page_Unloaded() is implemented directly, so that we don't need to alter every Page.
Can you please tell me how to create such a custom Page-class?
Thanks in advance for any help!!
Kind regards!
You could create a base Page class that all your pages inherit from which registers the event in the constructor...
public class BasePage : Page
{
public BasePage()
{
Unloaded += Page_Unloaded;
}
void Page_Unloaded(object sender, RoutedEventArgs e)
{
}
}
Then all your pages could inherit from that...
public partial class Page1 : BasePage
{
public Page1()
{
InitializeComponent();
}
}
...and in the xaml of each page...
<base:BasePage x:Class="WPFApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:WPFApp">
<Grid>
</Grid>
</base:BasePage>

Categories

Resources