I am using prism and it's not a Prism problem but I guess how forms works.
I have a master page and when I navigate to another page from the navigation menu It should show the back button on the title bar but it doesnt.
My code from the mainPage.xaml
<MasterDetailPage.Master>
<views:MenuPage/>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<ContentPage
BackgroundColor="Transparent" />
</MasterDetailPage.Detail>
Code behind
public partial class MainPage : IMasterDetailPageOptions, INavigatingAware
{
public MainPage()
{
InitializeComponent();
}
public bool IsPresentedAfterNavigation { get; } = Device.Idiom != TargetIdiom.Phone;
public void OnNavigatingTo(INavigationParameters parameters)
{
(Master as INavigatingAware)?.OnNavigatingTo(parameters);
(Master?.BindingContext as INavigatingAware)?.OnNavigatingTo(parameters);
}
}
What do I need todo to make the back button show when navigating to a page from master detail?
Many thanks
Related
I have a simple Xamarin.Forms app with a main page as TabbedPage which looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage
x:Class="PrismSample.Views.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="http://prismlibrary.com"
xmlns:views="clr-namespace:PrismSample.Views"
Title="Main Page"
prism:ViewModelLocator.AutowireViewModel="True">
<TabbedPage.Children>
<NavigationPage Title="Page1">
<x:Arguments>
<views:OnePage Title="Page 1" />
</x:Arguments>
</NavigationPage>
<NavigationPage Title="Page2">
<x:Arguments>
<views:TwoPage Title="Page 2" />
</x:Arguments>
</NavigationPage>
</TabbedPage.Children>
</TabbedPage>
On the page "OnePage" I have a button. When I tap on that button I want to navigate to a page named "ThreePage".
OnPage:
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
x:Class="PrismSample.Views.OnePage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True">
<ContentPage.Content>
<StackLayout Margin="20" Spacing="20">
<Label HorizontalOptions="CenterAndExpand" Text="Page 1" />
<Button
x:Name="Button1"
Command="{Binding ClickMeCommand}"
HorizontalOptions="FillAndExpand"
Text="Open Page 3" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
OnePageViewModel:
namespace PrismSample.ViewModels
{
public class OnePageViewModel : BindableBase
{
private readonly INavigationService navigationService;
public DelegateCommand ClickMeCommand { private set; get; }
public OnePageViewModel(INavigationService navigationService)
{
this.navigationService = navigationService;
ClickMeCommand = new DelegateCommand(async () => await ClickedAsync(), () => true);
Debug.WriteLine($"NavigationStack: {this.navigationService.GetNavigationUriPath()}", nameof(OnePageViewModel));
}
public Task ClickedAsync()
{
Debug.WriteLine($"You clicked me!", nameof(OnePageViewModel));
return navigationService.NavigateAsync("ThreePage");
}
}
}
App.xaml.cs
namespace PrismSample
{
public partial class App
{
public App() : this(null) { }
public App(IPlatformInitializer initializer) : base(initializer) { }
protected override async void OnInitialized()
{
InitializeComponent();
var result = await NavigationService.NavigateAsync("MainPage");
if(!result.Success)
{
System.Diagnostics.Debugger.Break();
}
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
containerRegistry.RegisterForNavigation<OnePage, OnePageViewModel>();
containerRegistry.RegisterForNavigation<TwoPage, TwoPageViewModel>();
containerRegistry.RegisterForNavigation<ThreePage, ThreePageViewModel>();
}
}
}
I expected the following:
When tapping on the button a navigation to the page "ThreePage" is done within the first tab. I also expected to have a "Back" button in the navigation bar.
What happens:
Nothing in the first tab. But if I switch to the second tab it shows the page "ThreePage" but also without a "Back" button.
What is going wrong here???
I have attached my project here:
https://www.dropbox.com/s/fuu2wo5zqhp52gk/08-TabbedNavigation.zip?dl=0
Navigating via TabbedPages is broken in the latest Prism released version (8.0.0.1909).
[Bug] Navigation when in Tabbed Pages doesn't change currently selected tab #2218
(It seems they finally have fixed this issue but they haven't released a new version until now)
So downgrade Prism.DryIoc to 7.2.0.1422 or wait for the next Prism release...
How to use Web View in "Onappering" Event?
protected async override void OnAppearing()
{
base.OnAppearing();
if (Settings.Session)
{
while (!BrowserMaster.IsInNativeLayout)
{
await Task.Delay(50);
CallServer(url);
}
}
}
i have a webview in Xamarin forms that used onappering event
but error
"The full view has not been loaded yet"
This not only waits for your web view instance to be ready, it also waits for the site to be loaded, so you can use your site's assets.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App1.TestPage">
<WebView x:Name="BrowserMaster" Source="https://google.com/" Navigated="BrowserMaster_Navigated" />
</ContentPage>
public partial class TestPage
{
public TestPage()
{
InitializeComponent();
}
bool _isFirstTime = true;
async void BrowserMaster_Navigated(object sender, WebNavigatedEventArgs e)
{
if (_isFirstTime)
{
_isFirstTime = false;
await BrowserMaster.EvaluateJavaScriptAsync("alert(document.title)");
}
}
}
In my XAML file, I used scroll view for scroll down but it does not work I can not find any issue where I did a couple of extra things here one is I add pull to refresh nuget and use it and I create a theme content class and I inherited it with default content page. another command in content page is working but scroll view does not support
Here my Xaml file
<views:BaseContentPage.Content>
<ScrollView BackgroundColor="White">
<controls:PullToRefreshLayout x:Name="PullToRefreshLayout" IsPullToRefreshEnabled="True" RefreshCommand="RefreshPatientDetailsPage">
<StackLayout>
// some code
</StackLayout>
</controls:PullToRefreshLayout>
</ScrollView>
</views:BaseContentPage.Content>
this is the Base content page I create
public abstract class BaseContentPage : ContentPage
{
public readonly BaseViewModel BaseViewModel;
protected bool IsNavigated;
public BaseContentPage(BaseViewModel baseViewModel)
{
BaseViewModel = baseViewModel;
}
protected abstract override void OnAppearing();
protected override void OnDisappearing()
{
IsNavigated = true;
}
}
I think this scroll view does not work because of the NuGet I put or it's the base content page
for android, I used this customer render
public class SortPaneListViewRendererAndroid : ListViewRenderer
{
public SortPaneListViewRendererAndroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.VerticalScrollBarEnabled = false;
var listView = Control as Android.Widget.ListView;
listView.DividerHeight = 1;
}
}
}
The reason this was happening is because you are nesting scrollable controls, Removing one of them will solve the issue
I am looking for tabs which will be on the bottom part of the page. I tried the xamarin forms TabbedPage, but for ios only the tabs are coming bottom and for android and windows the tabs are showing on the top. Is there any way to achieve this feature?
Edit: for new Xamarin.Forms projects you should use Xamarin.Forms Shell, it provides easy tabs and other great features.
To accomplish that you have 3 options:
1) To use new bottom tabbar native control you must have Xamarin Forms version 3.1 or above.
On your tabbed page you need to add the android specification for bottom placemente:
XAML
<?xml version="1.0" encoding="utf-8"?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
x:Class="YouProjectNameSpace.MyTabbedPage">
</TabbedPage>
Or c# code behind
using System;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
using Xamarin.Forms;
namespace YouProjectNameSpace
{
public partial class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
InitializeComponent();
On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
}
}
}
If you want more customization you can add:
<?xml version="1.0" encoding="utf-8"?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
BarBackgroundColor="#2196F3"
BarTextColor="White"
android:TabbedPage.BarItemColor="#66FFFFFF"
android:TabbedPage.BarSelectedItemColor="White"
x:Class="YouProjectNameSpace.MyTabbedPage">
</TabbedPage>
2) Create a custom renderer for Android of the tabbed page and move it to the bottom
using System;
using Xamarin.Forms;
namespace YouProjectNameSpace
{
public class CustomTabbedPage : TabbedPage
{
}
}
And the renderer:
using System;
using Android.Content;
using Android.Support.Design.Widget;
using Android.Support.V4.View;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android.AppCompat;
[assembly: ExportRenderer(typeof(CustomTabbedPage), typeof(CustomTabbedPageRenderer))]
namespace YouProjectNameSpace.Android
{
public class CustomTabbedPageRenderer : TabbedPageRenderer
{
public CustomTabbedPageRenderer(Context context): base(context)
{
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
this.InvertLayoutThroughScale();
base.OnLayout(changed, l, t, r, b);
}
private void InvertLayoutThroughScale()
{
this.ViewGroup.ScaleY = -1;
TabLayout tabLayout = null;
ViewPager viewPager = null;
for (int i = 0; i < ChildCount; ++i)
{
Android.Views.View view = GetChildAt(i);
if (view is TabLayout tabs)
tabLayout = tabs;
else if (view is ViewPager pager)
viewPager = pager;
}
tabLayout.ViewTreeObserver.AddOnGlobalLayoutListener(new GlobalLayoutListener(viewPager, tabLayout));
tabLayout.ScaleY = viewPager.ScaleY = -1;
}
private class GlobalLayoutListener : Java.Lang.Object, Android.Views.ViewTreeObserver.IOnGlobalLayoutListener
{
private readonly ViewPager viewPager;
private readonly TabLayout tabLayout;
public GlobalLayoutListener(ViewPager viewPager, TabLayout tabLayout)
{
this.viewPager = viewPager;
this.tabLayout = tabLayout;
}
public void OnGlobalLayout()
{
this.viewPager.SetPadding(0, -this.tabLayout.MeasuredHeight, 0, 0);
this.tabLayout.ViewTreeObserver.RemoveOnGlobalLayoutListener(this);
}
}
}
}
3) Use specific library like PXTabs, this one creates a full Xamarin Forms bottom tabs without any native code.
If you want to read more about bottom tabs and renderers:
Setting TabbedPage Toolbar Placement and Color
Xamarin.Forms: Official Bottom Navigation/Bottom Tabs on Android
BottomNavigationBarXF
c# code worked it.
using System;
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
using Xamarin.Forms;
namespace YouProjectNameSpace
{
public partial class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
InitializeComponent();
On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
}
}
}
I recently started building a Xamarin Forms application using Prism.
I'm not able to navigate with the MasterDetail Navigation. The button I use to navigate seems to not make the binding correctly. I never been able to reach the executed command with a breakpoint when clicking on the button.
Everything except the command binding seems to do the binding correctly, so I really have no idea on what is going on.
I already checked out the GitHub sample made available by the Prism team (HamburgerMenu project). I'm convince to use the exact same configuration as the sample but no way to make it works on my project.
Bellow is the code used currently:
MainPage.xaml
<MasterDetailPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MonkeyVault.Views.MainPage">
<MasterDetailPage.Master>
<NavigationPage Title="Required Foo" Icon="ic_menu.png">
<x:Arguments>
<ContentPage Title="Menu">
<StackLayout Padding="40">
<Label Text="{Binding UserName, StringFormat='Hello, {0}'}"/>
<Button Text="Sites" Command="{Binding NavigateCommand}" CommandParameter="Navigation/Sites" />
</StackLayout>
</ContentPage>
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Master>
</MasterDetailPage>
MainPageViewModel.cs
public class MainPageViewModel : BaseViewModel
{
#region Fields
private string _userName;
#endregion
#region Properties
public string UserName
{
get => _userName;
set => SetProperty(ref _userName, value);
}
public DelegateCommand<string> NavigateCommand;
public DelegateCommand NCommand;
#endregion
public MainPageViewModel(INavigationService navigationService)
: base(navigationService)
{
Title = "Main Page";
NavigateCommand = new DelegateCommand<string>(OnNavigateCommandExecuted);
}
private async void OnNavigateCommandExecuted(string path)
{
await _navigationService.NavigateAsync(path);
}
}
If someone has already encountered this problem or has any idea I would be greatful.
You need to create your DelegateCommand as a Property.
public DelegateCommand<string> NavigateCommand { get; set; }
Admittedly I am just guessing here, but I have had problems binding to Fields before and needed to change it to a property to get binding.