kesarling
kesarling

Reputation: 2204

Xamarin.Forms not Calling the Converter

I want the Label element in Xamarin.Forms application to occupy 15% of the height. So, I was suggested that I use the Converter. Following is the code I used:
My .xaml file

<?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:converters="clr-namespace:ConverterClasses"
             x:Class="App_for_e_Toilets.MainPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <converters:DeviceProperties x:Key="DeviceProperties" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout>
        <Label
            BackgroundColor="Green" 
            HeightRequest="{Binding DeviceHeight, Converter={StaticResource DeviceProperties}}"
            HorizontalOptions="FillAndExpand"
            HorizontalTextAlignment="Center"
            Text="Welcome"   
            TextColor="White"
            FontAttributes="Bold"
            VerticalTextAlignment="Center"/>
    </StackLayout>

</ContentPage>

My .xaml.cs file:

using System;
using System.Globalization;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace App_for_e_Toilets
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            BindingContext = this;
            InitializeComponent();
        }
        public double DeviceHeight = DeviceDisplay.MainDisplayInfo.Height;
    }
}

namespace ConverterClasses
{
    public partial class DeviceProperties : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double retVal = 0.50 * (double)value;
            return retVal;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

However, it seems that when I run the App, the converter is not being called (which I realised from the fact that the breakpoint at public object Convert is not breaking the code when execution. What am I doing wrong?

PS: It's my second day into Xamarin.Forms, so please bear with my code

Upvotes: 0

Views: 680

Answers (1)

Cfun
Cfun

Reputation: 9671

You have to start by implementing InotifyPropertyChanged and make the binded property with a backfield getter and setter in a ViewModel:

1- Create a helper class that will be the base for your ViewModels and that will implements the method to fire InotifyPropertyChanged event:

BaseViewModel.cs

public abstract class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void SetProperty<T>(ref T field, T value, [CallerMemberName] string name = null)
    {
        if (!Equals(field, value))
            OnPropertyChanged(name);
    }

    protected void OnPropertyChanged([CallerMemberName] string name = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

}

2- Create a clss for your ViewModel that inherits from BaseViewModel:

MainPageViewModel.cs

public class MainPageViewModel : BaseViewModel
{
private double labelheight;
public double LabelHeight
   {
     get => labelheight;
     set => SetProperty(ref labelheight, value);
   }
}

LabelHeight will store the height of your Label.

Since you want a percentage of the device height you can move DeviceDisplay.MainDisplayInfo.Height to your converter:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    return 0.15 * DeviceDisplay.MainDisplayInfo.Height;
}
HeightRequest="{Binding LabelHeight, Converter={StaticResource DeviceProperties}}"

3- Finally set your BindingContext to the ViewModel:

public MainPage()
{
    BindingContext = new MainPageViewModel();
    InitializeComponent();
}

Bindings works with properties not variables, also to inter-communicate between ui and code behind (logic) that a property value is changed it is necessary to implement Inotifypropertychanged interface.

Related Links:

MVVM Pattern

How to implement INotifyPropertyChanged in Xamarin.Forms

Inotifypropertychanged

Upvotes: 1

Related Questions