Yet Another Xamarin Forms Pinch Zoom - xamarin

I know nothing about Xamarin, but I inherited a project. The request is to pinch and zoom on one of the forms. I followed a tutorial on pinch and zoom on an image, and that worked out fine. However I do not seem to be able to apply to a whole page. I am using the default PinchToZoomContainer from the Xamarin dev site.
Here is how I am implementing it.
Here is where the PinchZoomContainer lives
I think this exposing the name space
xmlns:utilites="clr-namespace:MSTCEvents.Views.Utilities"
And this is how I think it needs to be applied.
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:Header Grid.Row="0"/>
<controls:CustomScrollView Grid.Row="1">
<utilites:PinchZoomContainer>
<utilites:PinchZoomContainer.Content>
a bunch of StackLayouts follow then
</utilites:PinchZoomContainer.Content>
</utilites:PinchZoomContainer>
</controls:CustomScrollView>
Just to see if I could get something simple to work I tried to add a final stacklayout at the end and just apply the container there, with no luck.
<StackLayout>
<utilites:PinchZoomContainer>
<utilites:PinchZoomContainer.Content>
<Image Source="Images/mstcLogo.jpg" />
</utilites:PinchZoomContainer.Content>
</utilites:PinchZoomContainer>
</StackLayout>
I am using Ctrl Left Mouse Click to simulate the gestures on an emulator.
cheers

I created a simple test about it: wrap the stacklayout inside the PinchToZoomContainer,and add the pinchGesture on page's GestureRecognizers,code as following:
<ContentPage.Content>
<local:PinchToZoomContainer>
<StackLayout>
<Label Text="This is a label" ></Label>
<Grid Padding="20">
<Image Source="pic.PNG" />
</Grid>
<Label Text="This is a label" ></Label>
</StackLayout>
</local:PinchToZoomContainer>
</ContentPage.Content>
codebehind:
var pinchGesture = new PinchGestureRecognizer();
pinchGesture.PinchUpdated += (s, e) => { // Handle the pinch };
GestureRecognizers.Add(pinchGesture);

Related

StackLayout stays above controls, but allows tap on buttons and entries in .Net MAUI

I have a StackLayout inside an AbsoluteLayout with some entries and a button, and the StackLayout has the LayoutBounds equal to "0,0,1,1" and the LayoutFlags equal to "All".
When I tap on the button, I show a Grid that has the same AbsoluteLayout properties described above, so that this Grid positions itself above the previous StackLayout, hiding all controls.
This Grid has a BoxView with a Gray color with some opacity, and an ActivityIndicator running.
Everything works as expected, except the fact that I still can tap on the entries (showing the virtual keyboard) and the button.
I know that this Grid is above the StackLayout with the controls, but why can I still tap on them ? I have the same solution in Xamarin Forms, and it works as expected, the controls have their events inhibited, since they are in a layer beneath.
Here is some sample code. For testing purposes, the Grid is already visible, but the intent is only making it visible after the tap on the button.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="PdC.Views.SamplePage"
Title="SamplePage">
<AbsoluteLayout>
<VerticalStackLayout
BackgroundColor="White"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
Padding="0,50,0,0"
Spacing="50">
<Entry
WidthRequest="200"
BackgroundColor="Yellow"
TextColor="Black"
Text="sample text on first entry" />
<Entry
WidthRequest="200"
TextColor="Black"
BackgroundColor="Yellow"
Text="sample text on second entry" />
<Button
Text="tap on me"
WidthRequest="200" />
</VerticalStackLayout>
<Grid
IsVisible="True"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<BoxView
ZIndex="9"
Grid.RowSpan="2"
BackgroundColor="Red"
VerticalOptions="FillAndExpand"
Opacity="0.5" />
<Frame
BackgroundColor="White"
Grid.Row="1">
<VerticalStackLayout
VerticalOptions="FillAndExpand">
<ActivityIndicator
IsRunning="True"
HorizontalOptions="Center"
Color="Red"/>
<Label
TextColor="Black"
Text="Please wait ..."
HorizontalOptions="Center"/>
</VerticalStackLayout>
</Frame>
</Grid>
</AbsoluteLayout>
</ContentPage>
As you can see, the entries and the button have their background color red with some transparency, meaning that the grid is above the stacklayout, but I still can tap on the entries (and the button) as the screenshots show.
Before tapping on the entry
After tapping the entry
Yes, it is the case as you said.
As a test, I replaced VerticalStackLayout with StackLayout and changed the property of BoxView from BackgroundColor="Red" to BackgroundColor="Transparent" .
Then I tested on xamarin forms, there was no such problem. This should be an issue in maui.
And I have created a new issue about this problem, you can follow it up here: https://github.com/dotnet/maui/issues/9514 .
Thanks for your feedback. Have a nice day.

Lower AppShell Flyout Below Navigation Bar

first time asking a question on here, sorry if I mess up the etiquette.
I am using AppShell in my Xamarin.Forms project and am using a flyout in combination with a tab bar.
What I want is for the AppShell flyout to always slide out below the navigation/title bar. Currently it covers the whole screen.
I know that I could use a custom view but I like the features and integration of AppShell. For now, I want to try to do this with AppShell.
I've tried a few things like setting the HeightRequest of the flyout and creating an empty header. The Idea will be to keep the buttons in the nav bar always clickable when the side menu is out.
Although, I'm starting to think that maybe this isn't possible with AppShell. Thanks!
How it's working now
What I want (never-mind the difference in flyout width)
You could try using SwipeView for this instead.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/swipeview
You could use the FlyoutPage instead. On Android, the navigation bar is present at the top of the page and displays a title, an icon, and a button that navigates to the detail page.
Create a FlyoutPage to load the MenuPage.
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:App10"
x:Class="App10.Page14" Title="Navigation Bar" FlyoutLayoutBehavior="Split">
<FlyoutPage.Flyout >
<local:FlyoutMenuPage x:Name="flyoutPage" />
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<local:ContactsPage />
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
Create a listview to simulate a Flyout of AppShell in FlyoutMenuPage.
<ListView x:Name="listView" x:FieldModifier="public">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:FlyoutPageItem}">
<local:FlyoutPageItem Title="Contacts" IconSource="check.png" TargetType="{x:Type local:ContactsPage}" />
<local:FlyoutPageItem Title="Reminders" IconSource="circle.png" TargetType="{x:Type local:ReminderPage}" />
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource}" />
<Label Grid.Column="1" Text="{Binding Title}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Please note, do not forget to set the NavigationPage in App.xaml.cs.
MainPage = new NavigationPage(new Page14());
For more details about it, you could refer to the code in GitHub. https://github.com/xamarin/xamarin-forms-samples/tree/main/Navigation/FlyoutPage

How to create a table with vertically sticky header and horizontally sticky first column using Xamarin Forms?

When displaying tabular data, I think that in some cases having an always visible header row and an always visible first column can really improve the readability and the overall usability of a table, especially if there is a lot of data in the table. The problem occurs when the table has to support both horizontal and vertical scrolling. A good example of such a table can be found from the NBA application when viewing box score of a past game. Here's an example image from the NBA Android application:
Example table from NBA mobile application
As you can clearly see from the image the header row is horizontally aligned with the actual table data and the first column is vertically aligned with the table data. I don't know whether or not it's an involuntary or a voluntary decision to prevent scrolling both horizontally and vertically with the same touch motion but that's a minor detail I don't care about.
I don't know how to implement this using Xamarin Forms. I am not interested in a closed source / paid solution since I would like to actually learn how to accomplish this by myself. I do realize that I most likely have to use custom renderers for both Android and IOS. My current idea is that I have an absolute layout where I have the following elements:
The first cell (it's stationary and the only stationary thing)
Rest of the header row inside a horizontal scrollview
First column inside a listview/stacklayout + vertical scrollview
The actual table data inside a listview + horizontal scrollview / stacklayout + horizontal and vertical scrollview
With this setup I would capture the touch event and send it to the other listviews/scrollviews, thus synchronizing the scrolling. In fact I can easily achieve the synchronized scrolling with the first column and the actual table data by setting the table data inside the same vertical scrollview as the first column. But I don't know how to synchronize the horizontal scrolling to the header row and I do believe that this can't be accomplished by clever component structure. I have tested only on Android so far that I can capture the touch event in a scrollview custom renderer's OnTouchEvent -method but I don't know how I could send this to the header row scrollview from the custom renderer.
Here is a draft XAML illustrating my approach.
<AbsoluteLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
HorizontalOptions="FillAndExpand">
<ScrollView
Orientation="Horizontal"
x:Name="HeaderScrollView"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<!-- Skip first column, leave it empty for stationary cell -->
<Label Text="Column 1" Grid.Row="0" Grid.Column="1" />
<Label Text="Column 2" Grid.Row="0" Grid.Column="2" />
<Label Text="Column 3" Grid.Row="0" Grid.Column="3" />
<Label Text="Column 4" Grid.Row="0" Grid.Column="4" />
</Grid>
</ScrollView>
<ScrollView
x:Name="FirstColumnScrollView"
Orientation="Vertical"
AbsoluteLayout.LayoutBounds="0,50,1,1"
AbsoluteLayout.LayoutFlags="SizeProportional"
BackgroundColor="Aqua">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout
Grid.Column="0"
Grid.Row="0"
BindableLayout.ItemsSource="{Binding DataSource}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Column1}" Grid.Row="0" Grid.Column="0" />
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
<ScrollView
x:Name="TableDataScrollView"
Grid.Column="1"
Grid.Row="0"
Orientation="Horizontal">
<StackLayout
BindableLayout.ItemsSource="{Binding DataSource}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Label Text="{Binding Column2}" Grid.Row="0" Grid.Column="0" />
<Label Text="{Binding Column3}" Grid.Row="0" Grid.Column="1" />
<Label Text="{Binding Column4}" Grid.Row="0" Grid.Column="2" />
<Label Text="{Binding Column5}" Grid.Row="0" Grid.Column="3" />
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</Grid>
</ScrollView>
<Label Text="First Column" BackgroundColor="White" AbsoluteLayout.LayoutBounds="0,0,200,50" />
</AbsoluteLayout>
As you can see the problem is that horizontal scrolling events between HeaderScrollView and TableDataScrollView are not shared and I don't know how to accomplish this in the best way possible or at all.
I do appreciate all the help and feedback with this!
What you are looking for is a DataGrid component with Frozen row and Frozen column feature. There are some third party components that would meet your requirements.
Syncfusion, Telerik and Infragistics DataGrids have the features you are looking for. Refer below links.
https://www.syncfusion.com/xamarin-ui-controls/xamarin-datagrid
https://www.telerik.com/xamarin-ui/datagrid
https://www.infragistics.com/products/xamarin/grids-and-lists/data-grid
There are few open-source DataGrid available as well. But not sure whether they have the row and column pinning features. Check the below links.
https://github.com/akgulebubekir/Xamarin.Forms.DataGrid
https://www.nuget.org/packages/Xamarin.Forms.DataGrid/
For open source, you could use Zumero DataGrid for Xamarin.Forms. It supports scrolling, both horizontal and vertical, optional top frozen header row, optional left frozen column and so on. You could download the sample code form the link below.
Zumero DataGrid for Xamarin.Forms: https://github.com/zumero/DataGrid/tree/8caf4895e2cc4362da3dbdd4735b5c6eb1d2dec4
For the sample code, if you get the error below, run as admin would be okay.
Build action 'EmbeddedResource' is not supported by one or more of the project's targets
Thanks for the help with this #Harikrishnan and #Wendy Zang - MSFT ! The Zumero DataGrid inspired me to do the motion event handling differently from the usual motion event handling flow. I basically created the following custom renderer for the AbsoluteLayout
using Android.Content;
using Android.Views;
using Test.Droid;
using Test.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using View = Android.Views.View;
[assembly: ExportRenderer(typeof(StatisticsTable), typeof(StatisticsTableRenderer))]
namespace Test.Droid
{
public class StatisticsTableRenderer : ViewRenderer
{
private View _headerScrollView;
private View _tableScrollView;
private float _startX;
public StatisticsTableRenderer(Context context) : base(context)
{
}
public override bool OnInterceptTouchEvent(MotionEvent ev)
{
if (_headerScrollView == null || _tableScrollView == null)
{
// Completely dependant on the structure of XAML
_headerScrollView = GetChildAt(0);
_tableScrollView = GetChildAt(1);
}
return true;
}
public override bool OnTouchEvent(MotionEvent ev)
{
if (ev.Action == MotionEventActions.Down)
{
_startX = ev.GetX();
}
var headerScroll = false;
if (_startX > _headerScrollView.GetX())
{
headerScroll = _headerScrollView.DispatchTouchEvent(ev);
}
var tableScroll = _tableScrollView.DispatchTouchEvent(ev);
return headerScroll || tableScroll;
}
}
}
As you can see I always intercept the motion event and then manually dispatch it to the children. However that was not enough. I had to prevent HeaderScrollView from scrolling when the motion event didn't start inside of it because the TableDataScrollView wouldn't scroll if the motion event wasn't started inside of it. I also had to create custom renderers for all scrollviews in this table. TableDataScrollView and HeaderScrollView were using the same custom renderer. The only thing that custom renderer implemented was OnInterceptTouchEvent like this:
public override bool OnInterceptTouchEvent(MotionEvent ev)
{
return false;
}
I am not quite sure why this is necessary but it seems to have done the trick for me. I suppose that sometimes the HeaderScrollView would intercept the motion event and this caused the header to scroll without scrolling of the table data.
The vertical scrollview aka FirstColumnScrollView in the question's XAML had to implement motion event handling differently because it is the parent of the TableDataScrollView and we are now handling motion events in a top-to-bottom manner instead of the default Android way of bottom-to-top. This caused issues where FirstColumnScrollView would simply handle the motion event and not pass it to TableDataScrollView which would then lead to the header and actual table data to be out of sync with each other. This is why I added the following custom renderer for it
using Android.Content;
using Android.Views;
using Test.Droid;
using Test.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using View = Android.Views.View;
[assembly: ExportRenderer(typeof(ChildFirstScrollView), typeof(ChildFirstScrollViewRenderer))]
namespace Test.Droid
{
public class ChildFirstScrollViewRenderer : ScrollViewRenderer
{
private View _childView;
public ChildFirstScrollViewRenderer(Context context) : base(context)
{
}
public override bool DispatchTouchEvent(MotionEvent e)
{
if (_childView == null)
{
_childView = GetChildAt(0);
}
_childView.DispatchTouchEvent(e);
return base.DispatchTouchEvent(e);
}
public override bool OnInterceptTouchEvent(MotionEvent ev)
{
return true;
}
}
}
In this ScrollView we always intercept/handle the motion event and we always send it to the child ScrollView first before handling the motion event.
I also had to do some minor adjustments to the XAML shown in the question. I set the starting X of HeaderScrollView to the width of the first column so it doesn't actually go under the static header of the first column. However this caused issues because I was unable to use width of the AbsoluteLayout (Why is it so hard in XAML?) to calculate the correct width for the HeaderScrollView. Now the width was set in a way that a part of the HeaderScrollView will always be outside of the viewport causing the last header to be never shown. So I added a "PaddingColumn" to the header grid with a width equal to the first column. I also had to add a "PaddingRow" to the FirstColumnScrollView grid for the same reason.
One other thing I had to do was to set the spacing of the grid inside FirstColumnScrollView to 0. Without that, there was this small gap from where you could start motion events that would only scroll the header and not the table data.
This is only the Android solution at the moment but I'll come back with the iOS one if I can accomplish it.

How to change the style of tab in segment control in xamarin forms

I have a segment control where I'm displaying tabs. But I'm not able to edit the style of the tab in Xamarin Forms. This is the UI I want
This is how I want to display my tabs in the segment control. I'm able to change the tint color, background color, and text color but none of that will get me a tab in this style. This is my current UI
This is XAML code where I implemented the segment control
<controls:SegmentedControl BackgroundColor="White" SelectedTextColor="Black" TintColor="#FFA500" x:Name="SegControl" ValueChanged="Handle_ValueChanged">
<controls:SegmentedControl.Children>
<controls:SegmentedControlOption Text="VENDOR NAME" />
<controls:SegmentedControlOption Text="PRODUCT/SERVICE" />
</controls:SegmentedControl.Children>
</controls:SegmentedControl>
<StackLayout x:Name="SegContent" />
</StackLayout>
<StackLayout Margin="0,30,0,0">
<StackLayout AbsoluteLayout.LayoutBounds=".20,1,1,.1" AbsoluteLayout.LayoutFlags="All" BackgroundColor="White" HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckNear">
<Image Margin="0,10,0,10" x:Name="imgNear" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Near" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckSearch">
<Image Margin="0,10,0,10" x:Name="imgSearch" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Search" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckCart">
<Image Margin="0,10,0,10" x:Name="imgCart" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Cart" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckAccount">
<Image Margin="0,10,0,10" x:Name="imgAccount" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Account" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
</StackLayout>
I'm not using any custom renderer for this segment control. Do I have to use a custom renderer for implementing the required UI? If yes how? Any suggestions?
SegmentedControl is not a built in Xamarin.Forms control. There are a few libraries that offer a SegmentedControl, so it would help to know which one you are using.
That said, the library author who created that SegmentedControl also made the platform renderers and so the different look on iOS vs Android is a result of that.
You can, of course, create your own custom renderer, but then why use the library?
Easier to me would be to make a control using Xamarin Forms, for instance you can use a grid that has a first row of two labels ( or Buttons) and a second row of 2 BoxViews that can act as the underline (very short height). Then just add TapGestureRecognizers to each Label (or just use a Buttons and style as needed).
Here's an example using Buttons and BoxViews:
XAML:
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="vBtn"
Text="VENDOR NAME" Clicked="Handle_Clicked"
TextColor="Black"
BackgroundColor="Transparent"
BorderColor="Transparent"
Grid.Row="0"
Grid.Column="0"/>
<Button x:Name="pBtn"
Text="PRODUCT/SERVICE" Clicked="Handle_Clicked"
TextColor="Black"
BackgroundColor="Transparent"
BorderColor="Transparent"
Grid.Row="0"
Grid.Column="1" />
<BoxView x:Name="vBox"
Color="#FFA500" HeightRequest="5"
Grid.Row="1"
Grid.Column="0"/>
<BoxView x:Name="pBox"
Color="Silver" HeightRequest="5"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
Code behind:
void Handle_Clicked(object sender, System.EventArgs e)
{
Button btn = sender as Button;
if (btn.Text == "PRODUCT/SERVICE")
{
vBox.Color = Color.Silver;
pBox.Color = Color.FromHex("#FFA500");
// Do anything else you need to do when the PRODUCT/SERVICE is tapped
}
else
{
vBox.Color = Color.FromHex("#FFA500");
pBox.Color = Color.Silver;
// Do anything else you need to do when the VENDOR NAME is tapped
}
}
No library or custom renderer needed.

Xamarin Forms Add Image with Text into Navigation Page Title

Does anyone know if there is a way to add an image into the title bar? So im wanting it to show the image right next to the normal title bar text (it's a logo). I can only seem to find a way to show text and i was hoping to steer clear of custom renderers unless it was worst case scenario.
This is currently what I have:
Im wanting to put a little logo directly to the left of the "News Feed" text.
I use either of these two ways in order to achieve that.
1.- Using NavigationPage.SetTitleIconImageSource as Isuru answer.
2.- Using NavigationPage.TitleView(see sample below)
<NavigationPage.TitleView>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Margin="10, 0, 0, 0" Source="{Binding TitleImage}" HorizontalOptions="CenterAndExpand" HeightRequest="25" WidthRequest="25" MinimumHeightRequest="25" MinimumWidthRequest="25" Grid.Row="0" Grid.Column="0" />
<Label Text="{Binding Title}" FontSize="Title" Grid.Row="0" Grid.Column="1" TextColor="White"/>
</Grid>
</NavigationPage.TitleView>
TitleImage and Title are BindingContext model properties.
Use 'SetTitleIcon' method in Xamarin.Forms.NavigationPage class.
public class MyPage : NavigationPage
{
public MyPage ()
{
var myContentPage = new MyContentPage (Color.White);
this.Push (myContentPage);
var s = "icon-45.png";
NavigationPage.SetTitleIcon (myContentPage, s);
}
}
for more detail go to this

Resources