Xamarin.Forms FlyoutPage is not working with Prism - xamarin

Please help me out. In order for you to understand my problem, I have replicated the scenario in sample application
As Xamarin.Forms introduced FlyoutPage page in 5.0 version, navigation is not working in one of the applications.
I am opening main page from app.xaml.cs like this await NavigationService.NavigateAsync("Page3");
FlyoutPage:
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:PrismNavigation.Views;assembly=PrismNavigation"
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="PrismNavigation.Views.Page3"
Title="Master">
<FlyoutPage.Flyout>
<ContentPage Title="Menu">
<StackLayout>
<Button Text="Page2" HeightRequest="50" WidthRequest="100" Command="{Binding NavigateCommand}" CommandParameter="Page2"></Button>
</StackLayout>
</ContentPage>
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<views:Page1></views:Page1>
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>
Page3ViewModel:
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PrismNavigation.ViewModels
{
public class Page3ViewModel : ViewModelBase
{
private readonly INavigationService navigationService;
public Page3ViewModel(
INavigationService navigationService)
: base(navigationService)
{
this.navigationService = navigationService;
this.NavigateCommand = new DelegateCommand<string>(this.NavigateCommandExecute);
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
base.OnNavigatedTo(parameters);
}
private void NavigateCommandExecute(string obj)
{
this.navigationService.NavigateAsync($"NavigationPage/{obj}");
}
public DelegateCommand<string> NavigateCommand { get; set; }
}
}
App:
using Prism;
using Prism.Ioc;
using PrismNavigation.ViewModels;
using PrismNavigation.Views;
using Xamarin.Essentials.Implementation;
using Xamarin.Essentials.Interfaces;
using Xamarin.Forms;
namespace PrismNavigation
{
public partial class App
{
public App(IPlatformInitializer initializer)
: base(initializer)
{
}
protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("Page3");
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IAppInfo, AppInfoImplementation>();
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<Page1>();
containerRegistry.RegisterForNavigation<Page2>();
containerRegistry.RegisterForNavigation<Page3, Page3ViewModel>();
}
}
}
When I am trying to navigate to Page2 from menu, i can not do that. When I click the button, navigate command is executed, but navigation is not happening.

Update:
In addition to my old answer, which you have fixed in the question, it seems that the FlyoutPage is not supported by Prism 8 according to this. It is planned for 8.1. So, you can either wait 8.1 or replace it with MasterDetailPage. I tried your example with MasterDetailPage and it worked fine for me:
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage 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"
x:Class="PrismNavigation.Views.Page3">
<MasterDetailPage.Master>
<ContentPage Title="Menu">
<StackLayout Padding="20">
<Button Text="Page2" HeightRequest="50" WidthRequest="100" Command="{Binding NavigateCommand}" CommandParameter="Page2"></Button>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<ContentPage Title="This is Page1"></ContentPage>
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
Old answer:
Seems like you didn't pass any parameter to your NavigateCommand. Try this
<StackLayout>
<Button Text="Page2" HeightRequest="50" WidthRequest="100" Command="{Binding NavigateCommand}" CommandParameter="Page2"></Button>
</StackLayout>

Related

Xamarin MasterDetail page black screen

I am implementing an APP with Xamarin using MasterDetail page
However in iOS encountered a black screen issue.
Here is example.
If I don't put a detail page in Xaml file like below.
<MasterDetailPage>
<MasterDetailPage.Master>
<ContentPage Title = "Menu">
<ScrollView>
...
</ScrollView>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<local:xxx_Page />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
During runtime. If I called below
Detail = new NavigationPage(page);
In iOS system. The phone enters a black screen
In Android. It works fine.
Is there any reason?
MasterDetailPage is obsolete. You can use FlyoutPage instead.
I used FlyoutPage to refer to your code and simply tested it on iOS without any problems, hope it can help you:
For .xaml file:
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FlyoutPageNavigation;assembly=FlyoutPageNavigation"
x:Class="FlyoutPageNavigation.MainPage">
<FlyoutPage.Flyout>
<ContentPage Title="Menu">
<ScrollView>
<StackLayout>
<Label Text="One"/>
<Label Text="Two"/>
<Label Text="Three"/>
</StackLayout>
</ScrollView>
</ContentPage>
</FlyoutPage.Flyout>
For .cs file:
using System;
using Xamarin.Forms;
namespace FlyoutPageNavigation
{
public partial class MainPage : FlyoutPage
{
public MainPage()
{
InitializeComponent();
Detail=new NavigationPage(new ContactsPage());
}
}
}
For more usage of Flyout, you can refer to the documentation: Xamarin.Forms FlyoutPage | Microsoft

ZXing QRCode Scanner Xamarin

I tried to implement the package ZXing.Net.Mobile.Forms
this is my xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
Title="{Binding Title}">
<ContentPage.Content>
<StackLayout>
<Label x:Name="scanResultText" />
<zxing:ZXingScannerView
OnScanResult="ScanViewOnScanResult"/>
</StackLayout>
</ContentPage.Content>
and this my xaml.cs :
public partial class QRCodePage : ContentPage
{
public QRCodePage()
{
InitializeComponent();
BindingContext = new QRCodeViewModel();
}
public void ScanViewOnScanResult(Result result)
{
Device.BeginInvokeOnMainThread(async () =>
{
scanResultText.Text = result.Text;
});
}
}
On my device i visualize the fragment but it seems not scanning
Try adding the following code (IsScanning="True") to your xaml:
<StackLayout>
<Label x:Name="scanResultText" />
<zxing:ZXingScannerView IsScanning="True"
OnScanResult="ScanViewOnScanResult"/>
</StackLayout>

How can I bind a XAML element on a template with the C# back end instead of in the XAML?

Here's what I have right now:
I have this template that's simplified for the question:
<?xml version="1.0" encoding="UTF-8"?>
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.RoundButtonText" x:Name="this">
<Label Text="ABC"
TextColor="{Binding LabelTextColor, Source={x:Reference this}}"
/>
</Frame>
and this C#
using Xamarin.Forms;
namespace Japanese.Templates
{
public partial class RoundButtonText : BaseFrameButtonTemplate
{
public RoundButtonText()
{
InitializeComponent();
// I would like to put the Label TextColor binding here instead of in the XAML
}
}
}
Can someone help me by telling me how I can add the binding for the label TextColor in the C# back end so that it changes in exactly the same way as it currently does when it's written as:
TextColor="{Binding LabelTextColor, Source={x:Reference this}}"
in XAML?
Remove the binding from the XAML and give the Label control an x:Name:
<?xml version="1.0" encoding="UTF-8"?>
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.RoundButtonText" x:Name="this">
<Label x:Name="label"
Text="ABC" />
</Frame>
Set up the binding and the property to bind to in C# code behind:
using Xamarin.Forms;
namespace Japanese.Templates
{
public partial class RoundButtonText : BaseFrameButtonTemplate
{
Color _labelTextColor;
public Color LabelTextColor {
get {
return _labelTextColor;
}
set {
if (_labelTextColor != value) {
_labelTextColor = value;
OnPropertyChanged("LabelTextColor");
}
}
}
public RoundButtonText()
{
InitializeComponent();
label.BindingContext = this;
label.SetBinding(Label.TextColorProperty, "LabelTextColor");
}
}
}
Now whenever the LabelTextColor property value is changed, the Label's TextColor property should change as well, just like with a XAML binding.

Cannot get this MasterDetail to work with Prism and listview

Below is my code that does not work could you spot what is wrong?
I am trying to convert this to prism
https://github.com/xamarin/xamarin-forms-samples/tree/master/Navigation/MasterDetailPage
I keep getting
"System.InvalidOperationException:
PushAsync is not supported globally on Android, please use a NavigationPage."
I am using a navigationpage(I think I do)
Could somebody look at the code .Below is all the code and tell me what Am I doing wrong??
many thanks!
app.cs
public partial class App : PrismApplication
{
public App(IPlatformInitializer initializer = null) : base(initializer) { }
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("MainPage/Navigation/ContactsPage");
}
protected override void RegisterTypes()
{
//Container.RegisterTypeForNavigation<NavigationPage>("Navigation");
Container.RegisterTypeForNavigation<MainNavigationPage>("Navigation");
Container.RegisterTypeForNavigation<MainPage,MainPageViewModel>();
Container.RegisterTypeForNavigation<ContactsPage,ContactsPageViewModel>();
Container.RegisterTypeForNavigation<MasterPage,MasterPageViewModel>();
Container.RegisterTypeForNavigation<ReminderPage,ReminderPageViewModel>();
Container.RegisterTypeForNavigation<TodoListPage,TodoListPageViewModel>();
}
}
MainNavigationPage.Xaml
<?xml version="1.0" encoding="utf-8" ?>
<NavigationPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="MasterDetailReferenceApp.Views.MainNavigationPage">
</NavigationPage>
MainPage.Xaml
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:views="clr-namespace:MasterDetailReferenceApp.Views;assembly=MasterDetailReferenceApp"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="MasterDetailReferenceApp.Views.MainPage"
Title="MainPage">
<MasterDetailPage.Master>
<views:MasterPage x:Name="masterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<views:ContactsPage />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
MainPage.cs
public partial class MainPage : MasterDetailPage,IMasterDetailPageOptions
{
public MainPage()
{
InitializeComponent();
}
public bool IsPresentedAfterNavigation => Device.Idiom != TargetIdiom.Phone;
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="MasterDetailReferenceApp.Views.MasterPage"
Icon="hamburger.png"
Title="Personal Organiser">
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand">
<ListView x:Name="listView"
RowHeight="60"
SeparatorVisibility="None"
BackgroundColor="White"
HasUnevenRows="true"
ItemSelected="OnMenuItemSelected">
>
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text="{Binding Title}" ImageSource="{Binding IconSource}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
MasterPage.cs
public partial class MasterPage : ContentPage
{
public ListView ListView => listView;
public MasterPage()
{
InitializeComponent();
var masterPageItems = new List<MasterPageItem>();
masterPageItems.Add(new MasterPageItem
{
Title = "Contacts",
//Uri = "ContactsPage",
Uri = "Navigation/ContactsPage",
IconSource = "contacts.png",
TargetType = typeof(ContactsPage)
});
masterPageItems.Add(new MasterPageItem
{
Title = "TodoList",
Uri = "Navigation/TodoListPage",
//Uri = "TodoListPage",
IconSource = "todo.png",
TargetType = typeof(TodoListPage)
});
masterPageItems.Add(new MasterPageItem
{
Title = "Reminders",
Uri = "Navigation/RemindersPage",
IconSource = "reminders.png",
TargetType = typeof(ReminderPage)
});
listView.ItemsSource = masterPageItems;
}
private void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (MasterPageItem)e.SelectedItem;
((MasterPageViewModel)BindingContext).NavigateCommand.Execute(item.Uri);
}
}
MasterPageItem
public class MasterPageItem
{
public string Title { get; set; }
public string Uri { get; set; }
public string IconSource { get; set; }
}
You need to set some NavigationPage as Detail for MasterDetailPage. Like this:
<MasterDetailPage.Detail>
<NavigationPage BarTextColor="White">
<x:Arguments>
<local:StatisticsPage />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
In this example first page in navigation page will be StatisticsPage.
Then, from StatisticsPageViewModel you can do
await _navigationService.NavigateAsync(new Uri(navParam, UriKind.Relative), useModalNavigation: isModal);
where navParam is nameof(SettingsPage). That will switch NavigationPage content to SettingsPage.
If you want to navigate away from MasterDetailPage then do
await NavigationService.NavigateAsync(nameof(OtherNonMasterDetailPage));
from your MasterDetailPageViewModel (not from the NavigationPage content's view model)

I want to customize Xamarin MasterDetail (Xamarin Crossplatform project) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Just check the image below. I want to change the color of marked areas on the Image. The image is a screenshot of UWP application developed using xamarin forms cross platform project (PCL).
I am using MasterDetail page navigation.
Now Color is changed as per my first requirement.
Now what I want is a screen design like below
Now I am getting a result as below
Result of second screen ie, after navigating to stock entry page
Source Code
1. MasterDetailsPage.Xaml
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="GST.Views.MasterDetailsPage"
Title="Stock Manager"
MasterBehavior="SplitOnPortrait"
BackgroundColor="#0063b1"
xmlns:pages="clr-namespace:GST.Views;assembly=GST">
<MasterDetailPage.Master >
<pages:MasterDetailsPageMaster x:Name="MasterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage >
<x:Arguments>
<pages:GST_Home />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
2. MasterDetailsPage.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace GST.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MasterDetailsPage : MasterDetailPage
{
public MasterDetailsPage()
{
InitializeComponent();
MasterPage.ListView.ItemSelected += ListView_ItemSelected;
}
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as MasterDetailsPageMenuItem;
if (item == null)
return;
var page = (Page)Activator.CreateInstance(item.TargetType);
Detail.Title = item.Title;
IsPresented = false;
Detail.Navigation.PushAsync(page);
MasterPage.ListView.SelectedItem = null;
}
}
}
3. MasterDetailsPageDetail.xaml
<?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="GST.Views.MasterDetailsPageDetail"
BackgroundColor="{StaticResource Key=background-color}"
Title="Master GST Title Detailed" >
<StackLayout Padding="10">
<Label Text="This is a detail page. To get the 'triple' line icon on each platform add a icon to each platform and update the 'Master' page with an Icon that references it."/>
</StackLayout>
</ContentPage>
4.MasterDetailsPageDetail.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace GST.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MasterDetailsPageDetail : ContentPage
{
public MasterDetailsPageDetail()
{
InitializeComponent();
// NavigationPage.SetHasBackButton(this, false);
// NavigationPage.SetHasNavigationBar(this, false);
}
}
}
5. MasterDetailsPageMaster.xaml
<?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="GST.Views.MasterDetailsPageMaster"
Title="Home">
<StackLayout>
<ListView x:Name="ListViewMenuItems"
SeparatorVisibility="None"
HasUnevenRows="true"
ItemsSource="{Binding MenuItems}">
<ListView.Header>
<Grid BackgroundColor="#03A9F4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="80"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Label
Grid.Column="1"
Grid.Row="2"
Text="AppName"
Style="{DynamicResource SubtitleStyle}"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,10" HorizontalOptions="FillAndExpand">
<Label VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center"
Text="{Binding Title}"
FontSize="24"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
6.MasterDetailsPageMaster.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace GST.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MasterDetailsPageMaster : ContentPage
{
public ListView ListView => ListViewMenuItems;
public MasterDetailsPageMaster()
{
InitializeComponent();
BindingContext = new ViewModels.MasterDetailsPageMasterViewModel();
}
}
}
7.MasterDetailsPageMenuItem.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GST.Views
{
public class MasterDetailsPageMenuItem
{
public MasterDetailsPageMenuItem()
{
TargetType = typeof(MasterDetailsPageDetail);
}
public int Id { get; set; }
public string Title { get; set; }
public Type TargetType { get; set; }
}
}
8.GST_Home.xaml -- Home Dash
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
NavigationPage.HasNavigationBar="False"
Title="Home Dash"
x:Class="GST.Views.GST_Home">
<StackLayout Padding="10">
<Label Text="This is a detail page. To get the 'triple' line icon on each platform add a icon to each platform and update the 'Master' page with an Icon that references it."/>
</StackLayout>
</ContentPage>
9.GST_Home.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace GST.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class GST_Home : ContentPage
{
public GST_Home()
{
InitializeComponent();
}
}
}
If you want full source code please refer my code which is uploaded on Google Drive: https://drive.google.com/file/d/0B2XtD2dQvEhzb1NnNGdydG91S0k/view?usp=sharing
If you wish to maintain the color of Title bar through out the app then you can write the following code inside the OnLaunched in the App.xaml.cs within Xamarin.UWP client project. For more please refer to Customizing Title Bar and Status Bar in Universal Windows Platform (UWP).
if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.ApplicationView"))
{
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
if (titleBar != null)
{
titleBar.ButtonBackgroundColor = Colors.Red;
titleBar.ButtonForegroundColor = Colors.White;
titleBar.BackgroundColor = Colors.Red;
titleBar.ForegroundColor = Colors.White;
}
}
And if you want to custom tool bar background color, you could set the BarBackgroundColor of the NavigationPage. You can do something like the following code.
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
......
var nav = new NavigationPage();
nav.PushAsync(page);
nav.BarBackgroundColor = Color.MediumPurple;
Detail = nav;
}

Resources