Shell navbar with trailing edge text - c#

Is there a way to put a "trailing edge" text on a Shell navbar like on this pic?
I'm refactoring a project to use Shell. Before, it was done by changing the toolbar item when the user taps monthly, weekly or daily on that specific page. But now, I'm using Shell with flyout and the tabs are from CommunityToolkit TabView so the "pages" on the tabs are no longer contant pages but content views.
If I add a toolbar it will appear on all views, not only on this specific view.
I would like to add a text at the final of the navbar only on that specific view and change it when the user taps the monthly, weekly or daily options.
This is Xamarin Forms project.
Thanks!

You can achieve it by ViewModel and TapGestureRecognizer.
ViewModel:
namespace Forms_Shell.ViewModels
{
public class Page1ViewModel : INotifyPropertyChanged
{
public ICommand TapCommand { get; }
string selection;
public string Selection
{
get => selection;
set
{
selection = value;
OnPropertyChanged(nameof(Selection));
}
}
public Page1ViewModel()
{
Selection = "Monthly";
TapCommand = new Command<string>(Show);
}
private void Show(string a)
{
Selection = a;
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I don't know the xaml code of the monthly, weekly or daily options, so I use label as an example to replace it. Add a TapGestureRecognizer attached to Label:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:Forms_Shell.ViewModels"
x:Class="Forms_Shell.Views.Page1"
Title="Page1">
<ContentPage.BindingContext>
<vm:Page1ViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="{Binding Selection}"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout Orientation="Horizontal" Padding="50,20">
<Label x:Name="Monthly" Text="Monthly" HorizontalOptions="CenterAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Source={Reference Monthly},Path=Text}"
Command="{Binding TapCommand}"/>
</Label.GestureRecognizers>
</Label>
<Label Text="Weekly" x:Name="Weekly" HorizontalOptions="CenterAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Source={Reference Weekly},Path=Text}"
Command="{Binding TapCommand}"/>
</Label.GestureRecognizers>
</Label>
<Label Text="Daily" x:Name="Daily" HorizontalOptions="CenterAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Source={Reference Daily},Path=Text}"
Command="{Binding TapCommand}"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Update:
<ContentPage
...
xmlns:local="clr-namespace:Forms_Shell.Views"
xmlns:vm="clr-namespace:Forms_Shell.ViewModels"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
...>
<ContentPage.BindingContext>
<vm:Page1ViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="{Binding Selection}"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout Orientation="Horizontal" Padding="50,20">
<xct:TabView TabStripPlacement="Top"
TabStripBackgroundColor="Blue"
TabStripHeight="50">
<xct:TabViewItem Text="Monthly"
x:Name="Monthly"
TextColor="White" TextColorSelected="Yellow" FontSize="12">
<xct:TabViewItem.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Source={Reference Monthly},Path=Text}"
Command="{Binding TapCommand}"/>
</xct:TabViewItem.GestureRecognizers>
<local:ContentView1/>
</xct:TabViewItem>
<xct:TabViewItem Text="Weekly"
x:Name="Weekly"
TextColor="White" TextColorSelected="Yellow" FontSize="12">
<xct:TabViewItem.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Source={Reference Weekly},Path=Text}"
Command="{Binding TapCommand}"/>
</xct:TabViewItem.GestureRecognizers>
<local:ContentView1/>
</xct:TabViewItem>
<xct:TabViewItem Text="Daily"
x:Name="Daily"
TextColor="White" TextColorSelected="Yellow" FontSize="12">
<xct:TabViewItem.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Source={Reference Daily},Path=Text}"
Command="{Binding TapCommand}"/>
</xct:TabViewItem.GestureRecognizers>
<local:ContentView1/>
</xct:TabViewItem>
</xct:TabView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
AppShell.xaml:
<Shell
...
xmlns:local="clr-namespace:Forms_Shell.Views"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
Title="Forms_Shell"
x:Class="Forms_Shell.AppShell">
<FlyoutItem Title="About" Icon="icon_about.png">
<ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</FlyoutItem>
<FlyoutItem Title="Browse" Icon="icon_feed.png">
<ShellContent Route="ItemsPage" ContentTemplate="{DataTemplate local:ItemsPage}" />
</FlyoutItem>
<FlyoutItem Title="Page1">
<ShellContent Route="Page1" ContentTemplate="{DataTemplate local:Page1}" />
</FlyoutItem>
</Shell>

Related

Popmodal from overriden back button

I am having some issues having my back button properly pop my modal after a user acknowledged that they will lose their changes if they do so. I suppose the issue lies in how to properly await the async method within a method that cannot be async due to how it is coded.
In my code behind I have the following method:
protected override bool OnBackButtonPressed()
{
base.OnBackButtonPressed();
Task<bool> confirm = DisplayAlert("Are you sure?", "All unsaved changes will be lost", "I'm Sure", "Cancel");
confirm.ContinueWith(x =>
{
if(x.Result)
{
var task = Navigation.PopModalAsync();
task.Wait();
}
});
return true;
}
I can see that it does properly hit my breakpoint inside if the user has clicked "I'm Sure". However, after doing that the modal still remains on the page.
I call my modal using the following method (it is wrapped in a NavigationPage as I wanted to be able to leverage Toolbar items, if this is an anti pattern please let me know)
private async void EditSwipeItem_Invoked(object sender, EventArgs e)
{
var unitOfWork = container.Resolve<IUnitOfWork>();
var invoked = sender as SwipeItem;
var element = invoked.BindingContext as InventoryModel;
await Navigation.PushModalAsync(new NavigationPage(new AddEditInventoryList(true, "8dc9e483-1d63-4629-b386-680ad7c9a324", element.InventoryId, unitOfWork)));
}
The code for the backbutton is based off of what I wrote for the CancelToolBar_Clicked, and it works correctly (That is, the modal is popped after the user acknowledges the prompt).
private async void CancelToolBar_Clicked(object sender, EventArgs e)
{
bool confirm = await DisplayAlert("Are you sure?", "All unsaved changes will be lost", "I'm Sure", "Cancel");
if(confirm)
await Navigation.PopModalAsync();
}
Edit:
This is what my XAML looks like:
<?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="Invenutory.Views.Inventory.AddEditInventoryList">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Save"
Order="Primary"
Clicked="SaveToolBarItem_Clicked"
Priority="1"/>
<ToolbarItem Text="Cancel"
Order="Secondary"
Clicked="CancelToolBar_Clicked"
Priority="0"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Padding="20">
<Frame HorizontalOptions="FillAndExpand"
VerticalOptions="Start"
Padding="20"
CornerRadius="8"
BorderColor="AliceBlue">
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"
Orientation="Vertical">
<Label Text="Name: " HorizontalOptions="Start" VerticalOptions="Start" />
<Entry HorizontalOptions="FillAndExpand" VerticalOptions="Start" Text="{Binding Name, Mode=TwoWay}" IsSpellCheckEnabled="True" IsTextPredictionEnabled="True" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"
Orientation="Vertical">
<Label Text="Description: " HorizontalOptions="StartAndExpand" VerticalOptions="Start"/>
<Editor HorizontalOptions="FillAndExpand" VerticalOptions="Start" Text="{Binding Description, Mode=TwoWay}" IsSpellCheckEnabled="True" IsTextPredictionEnabled="True" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"
Orientation="Vertical">
<Label Text="Count: " HorizontalOptions="Start" VerticalOptions="Start"/>
<Entry Keyboard="Numeric" HorizontalOptions="FillAndExpand" VerticalOptions="Start" Text="{Binding Count, Mode=TwoWay}" />
</StackLayout>
</StackLayout>
</Frame>
<Frame HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="20" CornerRadius="8" BorderColor="AliceBlue">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Image HorizontalOptions="FillAndExpand" VerticalOptions="Start" HeightRequest="150" Aspect="AspectFit" BackgroundColor="Gray" Source="{Binding CapturedPhoto}" />
<Button Text="Take Photo" HorizontalOptions="FillAndExpand" VerticalOptions="Start" Command="{Binding TakePhotoCommand, Mode=TwoWay}"/>
</StackLayout>
</Frame>
</StackLayout>
</ContentPage.Content>
</ContentPage>
I was able to solve this by updating my inner .ContinueWith to look as follows:
confirm.ContinueWith(x =>
{
if(x.Result)
{
MainThread.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopModalAsync();
});
}
});

Binding in generic control is null

I have several generic buttons. Both title and the corresponding icon are displayed correctly, but the tap function does not work.
HomePage.xaml with the ScanningApp control
<?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="primetals.ScannerApp.Views.HomePage"
xmlns:controls="clr-namespace:primetals.ScannerApp.Controls"
xmlns:resource="clr-namespace:primetals.ScannerApp"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
BackgroundColor="White"
x:Name="self"
Title="{Binding Title}">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="controls:ScanningApp">
<Setter Property="WidthRequest" Value="220"></Setter>
<Setter Property="HeightRequest" Value="220"></Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="3*"></RowDefinition>
<RowDefinition Height="3*"></RowDefinition>
<RowDefinition x:Name="backgroundImageRow" Height="4*"></RowDefinition>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" HorizontalOptions="CenterAndExpand" Margin="0,10,0,10">
<!-- Application Logo -->
<Image Source="icon_scannerapp.png" WidthRequest="96" HeightRequest="96"></Image>
<!-- Welcome Text -->
<Label Text="{x:Static resource:ApplicationResources.WelcomeMessageLine1}" FontSize="Large">
</Label>
<Label FontSize="Large">
<Label.FormattedText>
<FormattedString>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageLine2}"></Span>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageSpareParts}" FontAttributes="Bold" FontSize="Large"></Span>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageOr}"></Span>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageSensorData}" FontAttributes="Bold" FontSize="Large"></Span>
<Span Text="!"></Span>
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
<!-- Scanning Applications -->
<StackLayout Orientation="Horizontal" Grid.Row="1" BindableLayout.ItemsSource="{Binding Apps}" HorizontalOptions="Center" VerticalOptions="Start">
<BindableLayout.ItemTemplate>
<DataTemplate>
<controls:ScanningApp Margin="0,0,5,0"
ImageSource="{Binding ImageUrl}"
TapImageSource="{Binding TapImageUrl}"
Text="{Binding Title}"
TappedCommand="{Binding BindingContext.AppTappedCommand, Source={x:Reference self}}"
TappedCommandParameter="{Binding}">
</controls:ScanningApp>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
<!-- Background Image -->
<Image x:Name="backgroundImage" Grid.Row="2" Source="background_scannerapp_PT.jpg" Aspect="AspectFit" HorizontalOptions="Fill" VerticalOptions="Fill"></Image>
</Grid>
</ContentPage>
HomepageViewModel.cs:
AppTappedCommand is set correctly
this.AppTappedCommand = new DelegateCommand<ScanApplication>((app) => OnGotoScanPage(app));
this.Title = ApplicationResources.ApplicationTitleCaption;
public async void OnGotoScanPage(ScanApplication app)
{
NavigationParameters parameters = new NavigationParameters();
parameters.Add(Constants.Parameters.App, app.AppId);
await this.NavigationService.NavigateAsync($"{nameof(ScanPage)}", parameters);
}
ScanningApp.xaml.cs:
After Clicking the button TappedCommand is null.
public static readonly BindableProperty TappedCommandProperty = BindableProperty.Create(nameof(TappedCommand), typeof(ICommand), typeof(ScanningApp), default(ICommand), Xamarin.Forms.BindingMode.OneWay);
public ICommand TappedCommand
{
get
{
return (ICommand)GetValue(TappedCommandProperty);
}
set
{
SetValue(TappedCommandProperty, value);
}
}
public static readonly BindableProperty TappedCommandParameterProperty = BindableProperty.Create(nameof(TappedCommandParameter), typeof(object), typeof(ScanningApp), null, Xamarin.Forms.BindingMode.OneWay);
public object TappedCommandParameter
{
get
{
return GetValue(TappedCommandParameterProperty);
}
set
{
SetValue(TappedCommandParameterProperty, value);
}
}
private bool OnExecuteTap()
{
img.Source = this.ImageSource;
if (this.TappedCommand != null && this.TappedCommand.CanExecute(this.TappedCommandParameter))
{
this.TappedCommand.Execute(this.TappedCommandParameter);
}
return false;
}
ScanningApp.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentView 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="primetals.ScannerApp.Controls.ScanningApp"
x:Name="self">
<Grid Padding="1" BackgroundColor="{StaticResource PrimetalsLightGrayColor}">
<Grid>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
</Grid.GestureRecognizers>
<Grid.RowDefinitions>
<RowDefinition Height="5*"></RowDefinition>
<RowDefinition Height="1*" ></RowDefinition>
</Grid.RowDefinitions>
<Image x:Name="img" Grid.Row="0" Source="{Binding ImageSource, Source={x:Reference self}}" Aspect="AspectFit" VerticalOptions="CenterAndExpand"
Margin="20"></Image>
<Label Grid.Row="1" Text="{Binding Text, Source={x:Reference self}}"
Margin="10,0,10,10"
FontSize="Medium" TextColor="{StaticResource PrimetalsAccentColor}"
VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
</Grid>
</Grid>
</ContentView>
Originally this sourcecode worked (about one year ago) (but there may be problems with new packages in VS). I hope you can help me. Thanks a lot!
br
It seems that there should be a TapGestureRecognizer_Tapped event handler in ScanningApp.xaml.cs from your code.
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
So you could do like :
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
img.Source = this.ImageSource;
if (this.TappedCommand != null && this.TappedCommand.CanExecute(this.TappedCommandParameter))
{
this.TappedCommand.Execute(this.TappedCommandParameter);
}
}

Xamarin Forms - Duplicate Toolbar Appearing On Pages Issue

I'm building a shopping cart and I have a very annoying problem with a double toolbar being displayed on my pages.
I spent several hours on this and having issues trying to fix it.
My current pages are setup like so:
MainHomePage (This contains a menu and an embedded page titled "MainHomePageDetail")
MainHomePageDetail (this contains a list of images where the user will click on it and it will take them to other pages as well.
PageBulkBuys (This is one of the pages that displays the product details etc)
Problem to be fixed.
I just want to remove the double toolbar that's currently being displayed on the homepage and also the subpages.
Note that if I were to click on one of the menu links, this problem disappears and it only shows one tool bar.
However If I click on one of the links in the homepage, it shows a double tool bar which is really strange.
I've tried a few solutions online but no luck.
Here's my code:
App.CS
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainHomePage());
}
MainHomePage 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="xxxxx.MainHomePage" xmlns:pages="clr-namespace:xxxxx">
<MasterDetailPage.Master>
<pages:MainHomePageMaster x:Name="MasterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage BarBackgroundColor="Black">
<x:Arguments>
<pages:MainHomePageDetail />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
MainHomePage CS
public partial class MainHomePage : MasterDetailPage
{
public MainHomePage()
{
InitializeComponent();
MasterPage.ListView.ItemSelected += ListView_ItemSelected;
}
[Obsolete]
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as MainHomePageMenuItem;
if (item == null)
return;
if (item.Id == 10) // BulkBuys
Navigation.PushAsync(new BulkBuys());
}
}
MainHomePageDetail 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="xxxx.MainHomePageDetail" Title="xxxx" BackgroundColor="Black">
<ContentPage.ToolbarItems>
<ToolbarItem Name="shoppingcarticon" IconImageSource="xxxxxx.png" Priority="0" Order="Primary" Activated="ShoppingCartClicked"/>
</ContentPage.ToolbarItems>
<StackLayout Padding="10">
<ScrollView HorizontalOptions="FillAndExpand">
<StackLayout>
<Image Source="xxxxx.png" WidthRequest="600" HeightRequest="50"/>
<Label x:Name="labelLoggedInUser" TextColor="White" FontAttributes="Bold" FontSize="18"></Label>
<!-- Banner 1 -->
<Frame x:Name="frame1" BackgroundColor="#2e2e2e">
<StackLayout>
<Image x:Name="Banner1Image" WidthRequest="600" HeightRequest="200">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="BtnBulkBargains"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Frame BackgroundColor="Green" HasShadow="False" Padding="5" HorizontalOptions="Center" WidthRequest="250" HeightRequest="20" CornerRadius="00">
<Label x:Name="Banner1Text" FontAttributes="Bold" FontSize="18" TextColor="White" WidthRequest="80" HorizontalTextAlignment="Center" ></Label>
</Frame>
<Label x:Name="Banner1Header" TextColor="White" HorizontalTextAlignment="Center"></Label>
</StackLayout>
</Frame>
<!-- Banner 2 -->
<Frame x:Name="frame2" BackgroundColor="#2e2e2e">
<StackLayout>
<Image x:Name="Banner2Image" WidthRequest="600" HeightRequest="125"></Image>
</StackLayout>
</Frame>
MainHomePageDetail CS
public MainHomePageDetail()
{
InitializeComponent();
}
private void ShoppingCartClicked(object sender, EventArgs e)
{
Navigation.PushAsync(new ViewFBShoppingCart());
}
BulkBuysPage 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="xxxx.PageBulkBuys"
Title="Bulk Buys"
BackgroundColor="Black"
NavigationPage.HasBackButton="True">
<ContentPage.ToolbarItems>
<ToolbarItem Name="shoppingcarticon" IconImageSource="xxxx.png" Priority="0" Order="Primary" Activated="ShoppingCartClicked"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout>
<Image Source="xxxx.png" WidthRequest="600" HeightRequest="50"/>
<ListView x:Name="productsListView"
HasUnevenRows="True"
VerticalOptions="FillAndExpand"
SeparatorVisibility="None"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Frame HasShadow="True" Padding="20" Margin="20">
<StackLayout>
<Image Source="{Binding featured_src}"/>
<Label x:Name="labelProductTitle" Text="{Binding title}" FontSize="Medium" />
<Frame BackgroundColor="Red" Padding="5" HorizontalOptions="Center" WidthRequest="80" HeightRequest="20" CornerRadius="00">
<Label WidthRequest="40" Text="{Binding price, StringFormat='${0}'}" TextColor="White" HorizontalTextAlignment="Center"></Label>
</Frame>
</StackLayout>
</Frame>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
BulkBuysPage CS
public PageBulkBuys()
{
InitializeComponent();
}
private void ShoppingCartClicked(object sender, EventArgs e)
{
Navigation.PushAsync(new ViewFBShoppingCart());
}
Any help would greatly be appreciated.
Because you used the NavigationPage in your App.cs,it will create a toolbar for you:
MainPage = new NavigationPage(new MainHomePage());
try to change it to :
MainPage = new MainHomePage();
or use NavigationPage.SetHasNavigationBar method in your MainHomePage to hide the toolbar :
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainHomePage());
}
public MainHomePage()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
MasterPage.ListView.ItemSelected += ListView_ItemSelected;
}

Image not getting the Class ID - Xamarin Forms

I have several images in my XAML as follows (for this example I included two images).
<StackLayout Orientation="Horizontal" HorizontalOptions="Fill" Padding="0,5,0,5">
<Image x:Name="Image1" ClassId="{Binding Image1}" Source="tickoff.png" HeightRequest="18">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="SelectedImage"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Label Text="Asian Foods" FontSize="16" HorizontalOptions="Center" Margin="5,0,0,0"
TextColor="{StaticResource greyishBrown}"/>
</StackLayout>
StackLayout Orientation="Horizontal" HorizontalOptions="Fill" Padding="0,5,0,5">
<Image x:Name="Image2" ClassId="{Binding Image2}" Source="tickoff.png" HeightRequest="18">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="SelectedImage"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Label Text="Japanese Foods" FontSize="16" HorizontalOptions="Center" Margin="5,0,0,0"
TextColor="{StaticResource greyishBrown}"/>
</StackLayout>
I want to check what image has been clicked by the user. Fort this I'm using ClassId. I have included ClassIds in all images. This has a single method in code behind and I'm accessing classId from there.
But I'm not getting the Id when user clicks an image. I'm new to C# and Xamarin Forms. Could someone help me.
public void SelectedImage(object sender, EventArgs eventArgs)
{
Image image = (Image)sender;
string imageString = image.ClassId;
DisplayAlert("Test", imageSender.ClassId,"OK");
//TODO
}
XAML
<StackLayout Orientation="Horizontal" HorizontalOptions="Fill" Padding="0,5,0,5">
<Image x:Name="Image1" ClassId="Image1" Source="tickoff.png" HeightRequest="18">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="SelectedImage"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Label Text="Asian Foods" FontSize="16" HorizontalOptions="Center" Margin="5,0,0,0" TextColor="{StaticResource greyishBrown}" />
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="Fill" Padding="0,5,0,5">
<Image x:Name="Image2" ClassId="Image2" Source="tickoff.png" HeightRequest="18">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="SelectedImage"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Label Text="Japanese Foods" FontSize="16" HorizontalOptions="Center" Margin="5,0,0,0" TextColor="{StaticResource greyishBrown}"
/>
</StackLayout>
C#
public void SelectedImage(object sender, EventArgs eventArgs)
{
Image image = (Image)sender;
string imageString = image.ClassId;
DisplayAlert("Test", imageString ,"OK");
//TODO
}

Picker not showing Items

Am new in xamarin forms,i have a picker and populated it with items but it can't display the items.here is my code.
Picker in Xaml
<StackLayout Margin="1">
<Picker x:Name="curr_picker" Title="select currency">
</Picker>
</StackLayout>
How i populated it in cs
curr_picker.Items.Add("UGX");
curr_picker.Items.Add("USD");
curr_picker.Items.Add("JPY");
Here is my full code
xaml
ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FX2.ForexRates"
Title="Forex Rates"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=".3*" />
<RowDefinition Height=".7*" />
</Grid.RowDefinitions>
<StackLayout Orientation="Vertical">
<!--Frame 1 -->
<Frame Margin="5" HasShadow="True" BackgroundColor="White" >
<Frame.OutlineColor>
<OnPlatform x:TypeArguments="Color" Android="Gray" iOS="#DCDCDC" />
</Frame.OutlineColor>
<StackLayout Orientation="Vertical">
<Image Source="searchbox.png" HorizontalOptions="EndAndExpand"/>
<Image Source="flag_uganda.png" HorizontalOptions="StartAndExpand"/>
</StackLayout>
</Frame>
<Frame Margin="5" HasShadow="True" BackgroundColor="White" >
<Frame.OutlineColor>
<OnPlatform x:TypeArguments="Color" Android="Gray" iOS="#DCDCDC" />
</Frame.OutlineColor>
<StackLayout Orientation="Vertical">
<Label Text="UGANDA" HorizontalOptions="Center" TextColor="#5dade2"/>
<Image Source="searchbox.png" HorizontalOptions="EndAndExpand"/>
<Label Text="Compare With" HorizontalOptions="Center" TextColor="#5dade2"/>
<StackLayout Margin="1">
<Picker x:Name="curr_picker" Title="select currency">
</Picker>
</StackLayout>
<Picker x:Name="option_picker" Title="BUY or SELL">
</Picker>
<Button Text="VIEW RATES" BackgroundColor="#0711a7" HorizontalOptions="FillAndExpand" TextColor="White" HeightRequest="65" Clicked="Button_Clicked"/>
</StackLayout>
</Frame>
</StackLayout>
</Grid>
</ContentPage>
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 FX2
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ForexRates : ContentPage
{
public ForexRates()
{
InitializeComponent();
curr_picker.Items.Add("UGX");
curr_picker.Items.Add("USD");
curr_picker.Items.Add("JPY");
option_picker.Items.Add("BUY");
option_picker.Items.Add("SELL");
}
private void Button_Clicked(object sender, EventArgs e)
{
//await Navigation.PushAsync(new MainActivity());
}
}
}
If you are using newest Xamarin.Forms, like version 2.5 or later, you probably should use ItemsSource instead of Items for data binding. In XAML it will look like this:
<Picker x:Name="picker">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
In CS like this:
var monkeyList = new List<string>();
monkeyList.Add("Baboon");
monkeyList.Add("Capuchin Monkey");
monkeyList.Add("Blue Monkey");
picker.ItemsSource = monkeyList;
Instead of simple string you can also use complex types, check more here:
https://developer.xamarin.com/guides/xamarin-forms/user-interface/picker/populating-itemssource/
From the docs:
However, a Picker doesn't show any data when it's first displayed. Instead, the value of its Title property is shown as a placeholder on the iOS and Android platforms:
When the Picker gains focus, its data is displayed and the user can select an item:

Categories