Xamarin.Forms Pages are merging together - xamarin

When I navigate to a new page, adding it to the stack, if it is not full height of the page, it shows part of that page and part of the previous page (like a modal). I have a Xamarin.Forms app which uses a master detail page. I have upgraded to Xamarin.Forms Nuget 2.3.3.168 and am on the latest Xamarin version for Visual Studio.
I also checked the Navigation stack when going to a new page and everything looks correct. I have 1 master page which is the menu and the detail page has a navigation page with more pages in the stack, they just display partially on top of each other.
The only other thing I have changed is when I needed to initialize my App() constructor by setting the MainPage to a new MasterDetail page because it was failing if I did not do that in the constructor for Android. Any ideas?
Here is my App.cs:
public App()
{
InitializeComponent();
var masterDetailPage = new MasterDetailPage
{
Master = new Page() { Title = "Title" },
Detail = new Page(),
IsPresented = false
};
App.Current.MainPage = masterDetailPage;
}
Then, when I figure out if the user is logged in or not, I reset the master detail page with this function:
public static void SetMainPage(Page newPage)
{
var rootPage = new NavigationPage(newPage) { BarBackgroundColor = Color.White};
_nav.Initialize(rootPage);
_dialogService.Initialize(rootPage);
App.Current.MainPage = new MasterDetailPage
{
Master = new Menu(),
Detail = rootPage,
BindingContext = new MowMagicMobileViewModelBase(),
IsPresented = false
};
}
Then from there I call Navigation PushAsync() to pop a page onto the stack.

Wow it was actually that I just did not set a background color at all. I guess if you do not explicitly set it for the page it is transparent, unless that gets inherited from somewhere?

I dont know if its the solution but i have masterdetail page too..
But my page is like this
Master = new MenuPage();// it is a content page
Detail = new NavigationPage(new HomePage());
try it to see
If you want to change background i did sth like that
public class NavigationPageBase:NavigationPage
{
public NavigationPageBase (ContentPage c):base(c)
{
/*if (c.GetType().Equals(typeof(LoginPage)))
SetHasNavigationBar(c, false);
else
SetHasNavigationBar(c, true);*/
SetHasNavigationBar(c, true);
BarBackgroundColor = Styles.toolbarColor;
BackgroundColor = Styles.bgPageColor;
}
}
and for detailpage you can use it for example like
Detail = new NavigationPageBase (new HomePage ());
And from your App() constructor you can do simply
MainPage = new MyMasterDetailPage();
Hope it helps

Related

Xamarin Forms iOS TitleBarTextColor not changing

To change the TitleBarTextColor so far I tried a lot and my code now does change the back button color and the area on the very top of the screen, but the title!
in my AppDelegate FinishedLaunching function (it's after Forms.Init() and before LoadApplication()):
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes
{
TextColor = UIColor.White
});
In my ViewModel:
(App.Current.MainPage as NavigationPage).BarBackgroundColor = Color.FromHex("#990000");
(App.Current.MainPage as NavigationPage).BarTextColor = Color.White;
And this is how I'm navigating between the pages (not all the pages):
await _navigationService.NavigateAsync(new Uri("http://wwww.x.com/NavigationPage/TabbedNavigationPage?selectedTab=XPage/Document", UriKind.Absolute));
I even try to call the ViewModel code after the Prism navigation but it doesn't work... I'm a beginner and don't fully comprehend Prism and or Xamarin Forms.
[EDIT] -> I also tried to create a new class and inherit it from NavigationPage, set the BarTextColor in its constructor and use that class in the navigation like this: await _navigationService.NavigateAsync(new Uri("http://wwww.x.com/NEWCLASSCREATED/TabbedNavigationPage?selectedTab=XPage/Document", UriKind.Absolute)); But, as you may know, it is still not working.
Here's a Image ;)
imageToSeeThatImNotLying
Thank you for your support!
So I finnaly managed to work this out...
What I had to do was to create a custom Content Page because all the other solutions wasn't working. So I created this custom renderer only in my iOS project:
[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomContentPageRenderer))]
namespace TestProject.iOS.Bll.Utils.Renderers
{
public class CustomContentPageRenderer : PageRenderer
{
public override void DidMoveToParentViewController(UIViewController parent)
{
base.WillMoveToParentViewController(parent);
var titleView = new UITextView();
var page = this.Element as ContentPage;
try
{
if (!string.IsNullOrEmpty(page.Title))
{
titleView.Text = page.Title;
titleView.TextColor = UIColor.White;
titleView.Font = UIFont.SystemFontOfSize(17, UIFontWeight.Regular);
var bgColor = page.BackgroundColor;
titleView.BackgroundColor = UIColor.FromRGBA((int)bgColor.R, (int)bgColor.G, (int)bgColor.B, 0);
parent.NavigationItem.TitleView = titleView;
parent.NavigationItem.TitleView.ContentMode = UIViewContentMode.ScaleAspectFit;
}
}
catch (Exception e)
{
}
}
}
}
And I also removed all the code that I puted before in my AppDelegate file and in the App.xaml.cs file as well. I left the codes from the ViewModels because it was changing the back button to white, and I deleted the new NagivationPage class that I created before.
I'm going to explain why I did some of the things that you saw there:
To change the Title I created a UITextView() and set it to my NavigationItem.TitleView of the parent page. I set titleView.Text = page.Title; because my original page already have a title, so I'm just reusing it. And the backgroundcolor I had to do all of that so the backgroundcolor property works just in the way that I wanted.
And this DidMoveToParentViewController function was just so it can do all that before NavigationAsync from Prism.

Do I create a new Navigation Page or Content Page when making a tabbed application?

I want to create an application with tabs. I don't need the functionality of a Navigation page that allows me to go back to the last screen. I just want the tab bar to allow me to select one of five pages.
Here's the code I have so far:
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
My question is which of the following should I use. Note that HomePage inherits from ContentPage.
// this is the one the app uses now. Do I really need to NavigationPage and then inside that another page HomePage?
var homePage = new NavigationPage(new HomePage())
{
Title = "Home",
Icon = "ionicons_2_0_1_home_outline_25.png"
};
// I thought this would be better but ContentPage constructor cannot take an argument
var homePage = new ContentPage(new HomePage())
{
Title = "Home",
Icon = "ionicons_2_0_1_home_outline_25.png"
};
// this is my latest thought but would like to hear from others
var homePage = new HomePage()
{
Title = "Home",
Icon = "ionicons_2_0_1_home_outline_25.png"
};
Children.Add(homePage);
It's recommended that a TabbedPage should be populated with
NavigationPage and ContentPage instances only. This will help to ensure
a consistent user experience across all platforms.
The quote above is from the official TabbedPage documentation.
You don't have to wrap a ContentPage by NavigationPage if it is not needed.
If HomePage is inheriting from a ContentPage then you can just create an instance of it and add to children the next way:
var homePage = new HomePage
{
Title = "Home",
Icon = "ionicons_2_0_1_home_outline_25.png"
};
Children.Add(homePage);
P.S.: Official documentation has covered navigation topics quite nicely. Please get familiar with it.

ARCGis Xamarin - MapView from previous page displays after navigating to new page

I have a 'main' map page from which the user can either add data to the map or click on existing data to see the details. This is done with PushModalAsync() where I navigate to a new page. My problem is in both of those new pages I have a new map with a new MapView that is 'underneath' the MapView from the 'main' page. Both the MapView and Map itself are new objects on the secondary pages.
After navigating to my new pages, the previous MapView shows in the area of the screen where it existed (on 'main' page) where my new MapView also exists. In other words, on my new map pages my map is laid out differently and partially sits higher in the layout than the 'main' map does. The part that sits higher is the only part of the new map that is visible and I can interact with. The part that sits on the same area is the 'main' map view and I cannot interact with it and it blocks my new map.
I tried this with PushAsync as well (not modal) and nothing changed. How is one supposed to have multiple maps in an app across multiple pages? Is this even possible with ArcGIS? This app used to be with Google Maps/Apple and the exact same layout worked just fine.
Edit: Code here (with irrelevant parts removed) This page is navigated to from another page with a map on it wherein this map is covered if it is laid out in the same area of the first map. From this page I navigate to a 3rd page where both maps show up. Removal works successfully, however when I try to add I get an error saying I cannot add a null child to a view group:
public partial class EventDetails : ContentPage
{
public Xamarin.Forms.Grid MapGrid = new Xamarin.Forms.Grid()
{
RowDefinitions =
{
new RowDefinition { Height = 220 },
new RowDefinition { Height = GridLength.Auto }
},
ColumnDefinitions =
{
new ColumnDefinition { Width = 500 }
},
HorizontalOptions = LayoutOptions.Center
};
public Map DetailMap;
public MapView MyDetailMapView = new MapView();
public EventDetails(MapLog eventDetails, string strMapType)
{
DetailMap = new Map(BasemapType.ImageryWithLabels, eventDetails.Latitude, eventDetails.Longitude, iMapDetail);
MyDetailMapView.Map = DetailMap;
MyDetailMapView.ViewpointChanged += MyMapView_ViewpointChanged;
var scrollView = new ScrollView
{
Content = mainStack
};
MapGrid.Children.Add(MyDetailMapView, 0, 0);
MapGrid.Children.Add(scrollView, 0, 1);
Content = MapGrid;
}
#if __ANDROID__
protected override void OnAppearing()
{
if (!MapGrid.Children.Contains(MyDetailMapView))
{
try
{
MapGrid.Children.Add(MyDetailMapView);
}
catch (Exception ex)
{
DisplayAlert("Err", ex.Message, "Ok");
}
}
base.OnAppearing();
}
protected override void OnDisappearing()
{
if (MapGrid.Children.Contains(MyDetailMapView))
MapGrid.Children.Remove(MyDetailMapView);
base.OnDisappearing();
}
#endif
}
EDIT*: I updated my Xamarin Forms version and ARCGIS Runtime and now the solution to remove/add the map does work without issue.
I had other similar problems with having two maps for android in Xamarin Forms ArcGIS and the solution was removing the MapView from the visual tree when you navigate to the new page.
You need to remove the MapView before you Navigate to the second page by:
[your parent layout].Children.Remove(MyMapView);
await Navigation.PushAsync(new SecondPage());
And in your first page you need to make sure to add the MapView back to the Visual Tree when you come back to the page:
protected override void OnAppearing()
{
if (!GridMap.Children.Contains(MyMapView))
GridMap.Children.Add(MyMapView);
base.OnAppearing();
}
That solved all my problems with two maps. Thanks to this post in ESRI forum
Navigation between 2 MapViews in Xamarin Android

How to navigate from detail Page to Master Detail Page? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
The button from detail page cannot go to a master detail page. It keeps displaying error "break exception". Maybe I am not implementing this right. Please help :(
Master detail page does not work like that. You do not navigate from master to detail and back. Master is always available but on Phone it slides out like a drawer and on tablet it is present along with the detail page if not intentionally hidden.
public class App : Application
{
MasterDetailPage masterdetail;
Page detailpage;
Page masterpage;
protected override void OnStart()
{
masterdetail= new MasterDetailPage();
detailpage = new MyDetailPage();
masterpage = new Page();
masterdetail.Master = masterpage;
masterdetail.Detail = detailpage;
MainPage = masterdetail;
}
}
On Phone
With the above example you would see the detailpage only unless you slide out left to right or change the masterdetail.IsPresented to true in code.
On Tablet
If masterdetail.IsPresent is true the masterpage would show to the left and the detail to the right without any other code modifying this.
IsPresented
What you may be looking for is accessing the IsPresented field from a button click.
public partial class MyDetailPage : ContentPage
{
Button abutton;
MyDetailPage()
{
abutton = new Button();
abutton.click += (o,s) => {App.masterdetail.IsPresented == true ? false : true}
}
}
General Usage
The general intention of this layout design being that that master page leads to sub navigation detail pages in something like a Contacts List -> Specific Contact Details type relationship.
https://developer.xamarin.com/guides/xamarin-forms/user-interface/navigation/master-detail-page/
Navigation To MasterDetail From Other Page
button.click += (o,s) =>
{
var detailpage = new Page();
var masterpage = new Page();
var masterdetailpage = new MasterDetailPage();
masterdetailpage.Master = masterpage;
masterdetailpage.Detail = detailpage;
App.Current.MainPage = masterdetailpage;
}
Doing the Same Thing From Xaml with Commands
The below example creates a command in the page's.cs code and binds it to to a button on the xaml for the page.
public partial class CurrentPage : ContentPage
{
private ICommand goToMasterDetailCommand;
public ICommand goToMasterDetail
{
return goToMasterDetailCommand ?? (goToMasterDetailCommand = new Command(async () => await ExecuteGoToMasterDetail()));
}
private async Task ExecuteGoToMasterDetail()
{
var detailpage = new Page();
var masterpage = new Page();
var masterdetailpage = new MasterDetailPage();
masterdetailpage.Master = masterpage;
masterdetailpage.Detail = detailpage;
App.Current.MainPage = masterdetailpage;
}
}
<Button
x:Name="GoToButton"
Text="Go To Master Detail"
HorizontalOptions="FillAndExpand"
Command="{Binding goToMasterDetail}"
IsVisible="true">
Please try
Application.Current.MainPage = new MasterDetailsPage();
Upon button click

How do you switch between two different Xamarin Form pages?

I'm trying to figure out how to switch between two different pages in Xamarin Forms.
I do not wish to use a NavigationPage (which has that little back arrow that is auto displayed.
I have a Login page (which is a ContentPage) and once the person has authenticated, I then need to navigate to my Dashboard page (which is a TabbedPage).
eg.
Next, one of the Tab's in the TabbedPage is the profile of the logged in user. As such, I need to log them out. So i'll have a button to log them out, which means I will need to navigate them back to the Login page (which was that ContentPage).
I feel like I have two modes the user might be in.
UnAuthorized. (ContentPage)
Authorized. (TabbedPage).
It's like I need to change the App's MainPage to be either one of those two?
To change MainPage to another just do:
App.Current.MainPage = new NavigationPage(new MyContentPage());
or
App.Current.MainPage = new MyContentPage();
BTW: You can use a NavigationPage and then HIDE the toolbar with:
NavigationPage.SetHasNavigationBar(this, false);
You can do navigation as usual by setting MainPage in your Application instance. Small sample.
namespace TestNavigation
{
public class App : Application
{
public App ()
{
// The root page of your application
MainPage = new MyPage1 ();
}
}
}
namespace TestNavigation
{
public class MyPage1 : ContentPage
{
public MyPage1 ()
{
var button = new Button () {
Text = "Click me"
};
button.Clicked += (object sender, EventArgs e) => {
Application.Current.MainPage = new MyPage2 ();
};
Content = new StackLayout {
Children = {
button
}
};
}
}
}
namespace TestNavigation
{
public class MyPage2 : ContentPage
{
public MyPage2 ()
{
Content = new StackLayout {
Children = {
new Label { Text = "Hello ContentPage" }
}
};
}
}
}
EDIT1
I submitted this answer but then I realised that I probably don't understand your problem.
EDIT2
Updated sample.
If you like to switch between the pages then you can simply do
Application.Current.MainPage=new YourPage();
How to Change MainPage in xamarin forms at runtime?
this is what i have done to get result
For a login page, the best practice is to use
await Navigation.PushModalAsync (new LoginPage());
Once you are on the LoginPage, you can use popModelAsync after the validation is passed:
await Navigation.PopModalAsync ();

Resources