Forum Xamarin.Forms

Use a TemplateBinding in ControlTemplate to set Grid Height throws exception

baramusebaramuse USMember, Beta ✭✭


I'm trying to use a custom navigation bar in my app leveraging the ControlTemplate.
My BasePageTemplate is a simple grid with two rows : one for the custom navigation bar, the second take the space left for the page content.

Now this is working for a set row height ("44" and "*").
TemplateBindings work for the custom navigation bar properties (Title for example) so that's validated as well.

What I'm trying to do is to bind the height of the RowDefinition of the first row (the custom navigation bar) so I can hide the custom navigation bar from the ViewModel.
That's where I'm stuck.

<ControlTemplate x:Key="BasePageTemplate">
            <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" ColumnSpacing="0" RowSpacing="0">
                    <RowDefinition Height="{TemplateBinding BindingContext.StatusBarHeight}"/>
                    <RowDefinition Height="*"/>
                    Text="{TemplateBinding BindingContext.Title}"
                <ContentPresenter VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Grid.Column="0" Grid.Row="1"/>

My BaseViewModel: (I use Fody to generate the correct PropertyChanged)

    public abstract class ViewModelBase : INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        public string Title { get; set; }
        public string ContentText { get; set; }
        public GridLength StatusBarHeight { get; set; } = new GridLength(44);

When running I get an exception :

System.InvalidOperationException: Operation is not valid due to the current state of the object.
  at Xamarin.Forms.TemplateBinding+<Apply>d__17.MoveNext () [0x0001f] in D:\a\1\s\Xamarin.Forms.Core\TemplateBinding.cs:82
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/
  at at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0002c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/
  at CustomHeaderTests.iOS.Application.Main (System.String[] args) [0x00001] in /Users/.../Documents/perso/github/XForms/CustomHeaderTests/CustomHeaderTests.iOS/Main.cs:17

I've attached the test project.

Thanks a lot for the support.


  • MadhuKumarMadhuKumar USMember ✭✭
    edited October 2018


    I tried with your code. Event I too got the same exception. But we have an alternate solution for your problem.

    Set Grid First Row Height to Auto and Bind the Height to Label. Which will help you to hide and show custom navigation bar.

    RowDefinition Height="Auto"

    public int StatusBarHeight { get; set; } = (44); _
    _Label HeightRequest="{TemplateBinding BindingContext.StatusBarHeight }".

Sign In or Register to comment.