For this example:
var vm.MyText = "ABC";
<Label Grid.Row="1" Text="{Binding MyText}" />
Is there a way that I can add an underscore to the text?
use TextDecorations="Underline" (requires 3.3.0)
<Label>
<Label.FormattedText>
<FormattedString>
<FormattedString.Spans>
<Span Text="This app is written in C#, XAML, and native APIs using the" />
<Span Text=" " />
<Span Text="Xamarin Platform" FontAttributes="Bold" TextColor="Blue" TextDecorations="Underline">
<Span.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding TapCommand, Mode=OneWay}"
CommandParameter="https://learn.microsoft.com/en-us/xamarin/xamarin-forms/"/>
</Span.GestureRecognizers>
</Span>
<Span Text="." />
</FormattedString.Spans>
</FormattedString>
</Label.FormattedText>
</Label>
You can use a FormattedString to apply different attributes, colors, etc.. to a label:
var formattedString = new FormattedString();
formattedString.Spans.Add(new Span { Text = "Stack, ", FontAttributes = FontAttributes.None });
formattedString.Spans.Add(new Span { Text = "Overflow, ", FontAttributes = FontAttributes.Italic });
label.FormattedText = formattedString;
re: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label#formatted-text
Edit: check this answer if you're running a XF version previous to 3.3.0, otherwise followe the accepted answer.
If you need is an underline, you must create an effect
using Xamarin.Forms;
namespace YourProjectNamespace.Effects
{
public class UnderlineTextEffect : RoutingEffect
{
public UnderlineTextEffect()
: base("YourProjectNamespace.UnderlineTextEffect")
{
}
}
}
Android implementation
using System;
using System.ComponentModel;
using Android.Graphics;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ResolutionGroupName("YourProjectNamespace")]
[assembly: ExportEffect(typeof(AndroidUnderlineTextEffect), "UnderlineTextEffect")]
namespace YourProjectNamespace.Android.Effects
{
public class AndroidUnderlineTextEffect : PlatformEffect
{
protected override void OnAttached()
{
((TextView)Control).PaintFlags |= PaintFlags.UnderlineText;
}
protected override void OnDetached()
{
}
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(args);
if (args.PropertyName == Label.TextProperty.PropertyName || args.PropertyName == Label.FormattedTextProperty.PropertyName)
((TextView)Control).PaintFlags |= PaintFlags.UnderlineText;
}
}
}
iOS implementation:
using System;
using System.ComponentModel;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ResolutionGroupName("YourProjectNamespace")]
[assembly: ExportEffect(typeof(AppleUnderlineTextEffect), "UnderlineTextEffect")]
namespace YourProjectNamespace.iOS.Effects
{
public class AppleUnderlineTextEffect : PlatformEffect
{
protected override void OnAttached()
{
SetTextUnderline();
}
protected override void OnDetached()
{
}
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(args);
if (args.PropertyName == Label.TextProperty.PropertyName || args.PropertyName == Label.FormattedTextProperty.PropertyName)
SetTextUnderline();
}
private void SetTextUnderline()
{
var text = ((UILabel)Control).AttributedText as NSMutableAttributedString;
var range = new NSRange(0, text.Length);
text.AddAttribute(UIStringAttributeKey.UnderlineStyle,
NSNumber.FromInt32((int)NSUnderlineStyle.Single),
range);
}
}
}
And on your XAML add the effect:
<?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:local="clr-namespace:YourProjectNamespace"
x:Class="YourProjectNamespace.UnderlineEffectPage">
<StackLayout>
<Label
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
Text="Underlined Text">
<Label.Effects>
<local:UnderlineTextEffect />
</Label.Effects>
</Label>
</StackLayout>
</ContentPage>
Related
I am converting my Xamarin Forms Application to .NET MAUI.
I am trying to migrate the Custom renderer from Xamarin to MAUI following this link Using Custom Renderers in .NET MAUI
Here is my Code:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCompatibility()
.ConfigureMauiHandlers(handlers =>
{
handlers.AddCompatibilityRenderer(typeof(CustomFrame), typeof(CustomShadowFrameRenderer));
});
return builder.Build();
}
CustomFrame:
public class CustomFrame : Frame
{
public CustomFrame()
{
}
}
Below is the Custom Renderer Class
public class CustomShadowFrameRenderer : FrameRenderer
{
public CustomShadowFrameRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && e.OldElement == null)
{
e.NewElement.HeightRequest = 1000;
e.NewElement.VerticalOptions = LayoutOptions.FillAndExpand;
}
}
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage" BackgroundColor="Red"
xmlns:local="clr-namespace:MauiApp1.Controls">
<local:CustomFrame BackgroundColor="Blue" HeightRequest="1000" Padding="20">
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Label
Text="Hello, World!"
SemanticProperties.HeadingLevel="Level1"
FontSize="32"
HorizontalOptions="Center" />
<Label
Text="Welcome to .NET Multi-platform App UI"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I"
FontSize="18"
HorizontalOptions="Center" />
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Center" />
</VerticalStackLayout>
</local:CustomFrame>
</ContentPage>
The Frame is not accepting the height Request in MAUI but the same works fine in Xamarin forms.
Below is the image for the same
I have create a sample to test your code and met the same problem. In addition, I even can't click the button in the CustomFrmae. It seems there are some compatibility issues about the FrameRender in the maui.
So I try to change the CustomRender to the CustomHandler. It worked well and you just need to change two place code.
In the CustomShadowFrameRenderer class, make it such as public class CustomShadowFrameRenderer : Microsoft.Maui.Controls.Handlers.Compatibility.FrameRenderer
In the MauiProgram.cs:
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler(typeof(CustomFrame), typeof(CustomShadowFrameRenderer));
})
Trying to fire a command inside a stacklayout with itemssource. I wonder why the NavigateToProductListViewShopTappedCommand is not getting fired.
Tried multiple command approaches:
1)
Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyShopsListViewModel}}, Path=NavigateToProductListViewShopTappedCommand}"
Command="{Binding BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"
Command="{Binding Path=BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"
None are not working
Code:
<?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:controls="clr-namespace:BoerPlaza.Controls.Shop"
xmlns:local="clr-namespace:BoerPlaza.ViewModels"
xmlns:behaviors="clr-namespace:BoerPlaza.Behaviors"
x:Class="BoerPlaza.Views.Shop.MyShopsPage"
x:Name="Page"
Title="Mijn winkels">
<ContentPage.Content>
<ScrollView>
<StackLayout Margin="{StaticResource margin-side-std}"
Padding="{StaticResource padding-top-bottom-std}"
BindableLayout.ItemsSource="{Binding Shops}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<controls:ShopCardTemplateView Shop="{Binding .}"
ControlTemplate="{StaticResource ShopCardTemplateView}">
<controls:ShopCardTemplateView.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyShopsListViewModel}}, Path=NavigateToProductListViewShopTappedCommand}"
CommandParameter="{Binding .}">
<!--Command="{Binding BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"-->
</TapGestureRecognizer>
</controls:ShopCardTemplateView.GestureRecognizers>
</controls:ShopCardTemplateView>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
Code behind
public partial class MyShopsPage : ContentPage
{
private readonly MyShopsListViewModel _viewModel;
public MyShopsPage()
{
InitializeComponent();
BindingContext = _viewModel = new MyShopsListViewModel(App.ShopDataStore, App.DialogService);
_viewModel.LoadShopsOnUserIdCommand.Execute("B22698B8-42A2-4115-9631-1C2D1E2AC5F7");
}
protected override void OnAppearing()
{
base.OnAppearing();
_viewModel.OnAppearing();
}
}
ViewModel:
[QueryProperty(nameof(UserId), nameof(UserId))]
public class MyShopsListViewModel : BaseViewModel
{
private string _userId;
private ObservableCollection<ShopDbViewModel> _shops;
private readonly IShopDataStore _shopDataStore;
private readonly IDialogService _dialogService;
public ObservableCollection<ShopDbViewModel> Shops
{
get
{
return _shops;
}
set
{
_shops = value;
OnPropertyChanged(nameof(Shops));
}
}
public void OnAppearing()
{
IsBusy = true;
}
public ICommand LoadShopsOnUserIdCommand { get; set; }
public ICommand NavigateToProductListViewShopTappedCommand { get; set; }
public MyShopsListViewModel(IShopDataStore shopDataStore, IDialogService dialogService)
{
this._shopDataStore = shopDataStore;
this._dialogService = dialogService;
Shops = new ObservableCollection<ShopDbViewModel>();
LoadShopsOnUserIdCommand = new Command<string>(async (string userId) => await ExecuteLoadShopsOnUserId(userId));
NavigateToProductListViewShopTappedCommand = new Command<ShopDbViewModel>(async (ShopDbViewModel shop) => await ExecuteNavigateToProductListViewShopTappedCommandAsync(shop));
}
private async Task ExecuteNavigateToProductListViewShopTappedCommandAsync(ShopDbViewModel shop)
{
if (shop == null)
return;
await Shell.Current.GoToAsync($"{nameof(ProductsPage)}?{nameof(MyProductsListViewModel.ShopId)}={shop.Id}");
}
public string UserId
{
get
{
return _userId;
}
set
{
_userId = value;
LoadShopsOnUserIdCommand.Execute(value);
}
}
private async Task ExecuteLoadShopsOnUserId(string userId)
{
var current = Connectivity.NetworkAccess;
if (current == NetworkAccess.Internet)
{
try
{
Shops.Clear();
var shops = await _shopDataStore.GetShopOnUserIdAsync(userId);
foreach(var shop in shops)
{
Shops.Add(shop);
}
}
catch (Exception ex)
{
await _dialogService.ShowDialog(ex.Message, "An error has occurred", "OK");
}
finally
{
IsBusy = false;
}
}
else
{
await _dialogService.ShowDialog("No active internet connection", "Connection error", "OK");
IsBusy = false;
}
}
}
If you define the ICommand in the ViewModel directly , you could set the binding path like following
Command="{Binding Path=BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"
I've found the problem
<?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:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:customcontrols="clr-namespace:BoerPlaza.Controls"
x:Class="BoerPlaza.Controls.Shop.ShopCardTemplateView">
<ContentView.Resources>
<ControlTemplate x:Key="ShopCardTemplateView">
<!-- Card Header -->
<!-- for displaying products and categories on homepage -->
<StackLayout Spacing="1"
HorizontalOptions="FillAndExpand"
Margin="{StaticResource margin-card}">
<!-- On click - shows the product detail view page -->
<StackLayout.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" />
</StackLayout.GestureRecognizers>
<!-- Image frame -->
<Frame BackgroundColor="{StaticResource image-box-color}"
CornerRadius="0"
HasShadow="False"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HeightRequest="100">
<!-- Product Image -->
....
As you can see this is the control template I'm using for the MyShopsPage. This is a shop card. Inside this shop card I already had an StackLayout.GestureRecognizers. Somehow when I was clicking on the control template, I was actually clicking on this.
I always thought everything flows from top to bottom in events, but this seems different. Something that is on top on something else does not mean anything in xaml.
Here is my code (it's uwp app). I'm wondering why the second binding {Binding ElementName=Items, Path=DataContext.IsStaggeringEnabled} is not working and how to fix it?
MainPage.xaml:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.DataContext>
<local:MainViewModel />
</Page.DataContext>
<StackPanel Orientation="Vertical">
<ItemsControl x:Name="Items"
ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerTransitions>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="{Binding ElementName=Items, Path=DataContext.IsStaggeringEnabled}" <!-- THIS IS NOT WORKING -->
FromVerticalOffset="-20"
FromHorizontalOffset="-20" />
</TransitionCollection>
</ItemsControl.ItemContainerTransitions>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Button Click="{x:Bind Redraw}">Redraw</Button>
</StackPanel>
</Page>
MainPage.xaml.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace App1
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
public void Redraw()
{
DataContext = new MainViewModel();
}
}
}
MainViewModel.cs:
using GalaSoft.MvvmLight;
using System.Collections.ObjectModel;
namespace App1
{
public class MainViewModel : ViewModelBase
{
public ObservableCollection<ItemViewModel> Items { get; set; } = new ObservableCollection<ItemViewModel>();
public bool IsStaggeringEnabled { get; set; } = true;
public MainViewModel()
{
for (var i = 0; i < 10; i++)
{
Items.Add(new ItemViewModel());
}
}
}
}
ItemViewModel.cs:
using GalaSoft.MvvmLight;
namespace App1
{
public class ItemViewModel : ViewModelBase
{
public static int Index = 0;
public string Name { get; set; }
public ItemViewModel()
{
Index++;
Name = $"{Index}";
}
}
}
Binding is not valid:
Maybe, Transitions are not laid in XAML tree so straightforwardly, therefore it would be impossible to access the control by ElementName. For workaround, try using {x:Bind} anyway.
<EntranceThemeTransition
IsStaggeringEnabled="{x:Bind ((local:MainViewModel)Items.DataContext).IsStaggeringEnabled, Mode=OneWay}"
FromVerticalOffset="-20"
FromHorizontalOffset="-20"/>
Maybe you need to change the way you create ViewModel:
xaml.cs
public MainViewModel vm = new MainViewModel();
public MainPage()
{
this.InitializeComponent();
DataContext = vm;
}
public void Redraw()
{
vm = new MainViewModel();
}
xaml
...
<EntranceThemeTransition IsStaggeringEnabled="{x:Bind vm.IsStaggeringEnabled,Mode=OneWay}"
FromVerticalOffset="-20"
FromHorizontalOffset="-20" />
...
So you can bind successfully.
how i can navigate user to dashboard page after i got Access token and user successfully logged in or error messege when user entred wrong username or password
here is my login viewmodel
using RoyalSales.Views;
using System.Windows.Input;
using Xamarin.Forms;
using RoyalSalesAPI.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Android.App;
using Android.Content.Res;
using RoyalSales.Helpers;
namespace RoyalSales.ViewModels
{
class LoginViewModel
{
private APIServices _APIServices = new APIServices();
public string Username { get; set; }
public string Password { get; set; }
public String Message { get; set; }
public ICommand Logincommand => new Command(async () =>
{
var accesssToken = await _APIServices.LoginAsync(Username, Password);
if (!string.IsNullOrEmpty(accesssToken))
{
Message = "login succeed";
Settings.Username = Username;
Settings.Password = Password;
Settings.AccessToken = accesssToken;
// here i want navigate user to dashboard page
}
else
{
Message = "wrong username or password";
// here i want show message dialoge to tell user theres an wrong username or
password
}
});
public ICommand LogOutcommand
{
get
{
return new Command( () =>
{
Settings.AccessToken = null;
});
}
}
public LoginViewModel()
{
if (!string.IsNullOrEmpty(Settings.Username))
{
Username = Settings.Username;
Password = Settings.Password;
}
}
}
}
here is my loginpage.cs
using Javax.Security.Auth;
using RoyalSales.Views;
using Android.Provider;
using RoyalSalesAPI.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using RoyalSales.ViewModels;
using RoyalSales.Helpers;
using Settings = RoyalSales.Helpers.Settings;
namespace RoyalSales
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Login : ContentPage
{
public APIServices aPIServices = new APIServices();
private string accessToken = Settings.AccessToken.ToString();
public Login()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
}
private async void Button_Clicked(object sender, EventArgs e)
{
}
}
}
here is my loginpage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="RoyalSales.Login"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:RoyalSales.ViewModels;assembly=RoyalSales"
Title="login page"
BackgroundColor="#F38906">
<ContentPage.BindingContext>
<viewModels:LoginViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout
Padding="20"
Orientation="Vertical"
Spacing="30">
<BoxView HeightRequest="20" />
<Image
HorizontalOptions="Center"
Source="almotaheda.png"
WidthRequest="175" />
<Label
FontSize="Large"
HorizontalOptions="Center"
Text="slogn"
TextColor="White" />
<Frame BackgroundColor="#FBD7AC" HasShadow="False">
<StackLayout Orientation="Vertical" Spacing="10">
<Entry
x:Name="UserNameEntry"
HeightRequest="40"
HorizontalTextAlignment="Center"
Placeholder="username"
PlaceholderColor="#F38906"
Text="{Binding Username}"
TextColor="Black" />
<Entry
x:Name="PasswordEntry"
HeightRequest="40"
HorizontalTextAlignment="Center"
IsPassword="True"
Placeholder="Password"
PlaceholderColor="#F38906"
Text="{Binding Password}"
TextColor="Black" />
</StackLayout>
</Frame>
<Label
FontSize="20"
Text="{Binding Message}"
TextColor="#FFFFFF" />
<Button
BackgroundColor="White"
Command="{Binding Logincommand}"
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="FillAndExpand"
Text="login"
TextColor="#F38906"
Clicked="Button_Clicked"/>
<BoxView HeightRequest="20" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
plese help my to navigate the user to dashboard page if successfuly logged in or error message if wrong username or password
You can use PushAsync or PushModalAsync after setting the AccessToken
For example:
await App.Current.MainPage.Navigation.PushAsync(new dashboardPage(), true);
In order to display an Alert from viewmodel you can use:
await Application.Current.MainPage.DisplayAlert("Error", "Login message here", "Dismiss");
I am having trouble getting bindings defined in a ControlTemplate to work against my model.
Notice in the below ControlTemplate, I am using a TemplateBinding to bind to a property called Count (olive label). I am using Parent.Count as prescribed by this article, but neither values of Parent.Count nor Count are working.
The following page uses the ControlTemplate. Just to prove my ViewModel works I have a gray Label bound to the Count property as well.
Notice the resulting screen. The gray label is showing the Count property. The olive label from the ControlTemplate is not showing anything.
How can I make the Label in the ControlTemplate show the Count property from the ViewModel?
VIEW MODEL
namespace SimpleApp
{
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
_count = 10;
Uptick = new Command(() => { Count++; });
}
private int _count;
public int Count
{
get { return _count; }
set
{
_count = value;
OnPropertyChanged("Count");
}
}
public ICommand Uptick { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
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"
xmlns:local="clr-namespace:SimpleApp"
x:Class="SimpleApp.MainPage"
ControlTemplate="{StaticResource ParentPage}">
<StackLayout>
<Button Command="{Binding Uptick}" Text="Increment Count" />
<Label Text="{Binding Count}" BackgroundColor="Gray" />
</StackLayout>
</ContentPage>
CODE BEHIND
Notice the BindingContext is set to MainViewModel here. I need to use my own ViewModel and not the code behind.
namespace SimpleApp
{
public partial class MainPage : ContentPage
{
public MainPage()
{
BindingContext = new MainViewModel();
InitializeComponent();
}
}
}
CONTROL TEMPLATE
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SimpleApp.App">
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="ParentPage">
<StackLayout>
<Label Text="{TemplateBinding Parent.Count}" BackgroundColor="Olive" />
<ContentPresenter />
</StackLayout>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
On your ControlTemplate please use the following code:
<Label Text="{TemplateBinding BindingContext.Count}" BackgroundColor="Olive" />
It seems that BindingContext is not being automatically applied to your ContentPage child, maybe it could be a bug in Xamarin.