Reputation: 2204
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
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:
How to implement INotifyPropertyChanged in Xamarin.Forms
Upvotes: 1