I'm trying to use DynamicResource to set the height of rows in a grid but it is not working and I am unsure why. I've created a default Xamarin project in Visual Studio to test.
Here is the relevant page:
MainPage.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"
x:Class="TestDynamicResource.MainPage">
<StackLayout>
<Grid BackgroundColor="Orange">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="{DynamicResource RowHeight}" />
<RowDefinition Height="{Binding Source={DynamicResource RowHeight}, Converter={StaticResource TestConverter}}"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="Testing Color Change on this one" TextColor="{DynamicResource LabelColor}"/>
<Label Grid.Row="1" Text="Testing Height" />
<Label Grid.Row="2" Text="Testing Height Change on this one through binding"/>
</Grid>
</StackLayout>
</ContentPage>
And here is the main App class:
public partial class App : Application
{
public App()
{
Resources.Add("TestConverter", new TestConverter());
Resources["RowHeight"] = new GridLength(15);
Resources["LabelColor"] = Color.Brown;
InitializeComponent();
MainPage = new MainPage();
UpdateResources();
}
private async void UpdateResources()
{
Console.WriteLine("Wait 5 seconds");
await System.Threading.Tasks.Task.Delay(5000);
Console.WriteLine("Change color to RED and height to 500");
Resources["RowHeight"] = new GridLength(500);
Resources["LabelColor"] = Color.Red;
Console.WriteLine("Wait 5 seconds");
await System.Threading.Tasks.Task.Delay(5000);
Console.WriteLine("Change color to BLUE and height to 25");
Resources["RowHeight"] = new GridLength(25);
Resources["LabelColor"] = Color.Blue;
Console.WriteLine("Wait 5 seconds");
await System.Threading.Tasks.Task.Delay(5000);
Console.WriteLine("Change color to DeepPink and height to 100");
Resources["RowHeight"] = new GridLength(100);
Resources["LabelColor"] = Color.DeepPink;
}
protected override void OnStart()
{
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
And the converter being used:
TestConverter.cs
public class TestConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is DynamicResource dr)
{
if (Application.Current.Resources.ContainsKey(dr.Key))
{
if (Application.Current.Resources[dr.Key] is GridLength gridLengthResult)
return gridLengthResult;
}
else
{
Console.WriteLine("Resources do not contain: " + dr.Key);
}
}
Console.WriteLine("Returning null");
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Here is a result of when the application is started:
As you can see, the height never changes.
I've tried this for colors, padding, corner radius of frames, and grid row definition height -- the height is the only one that doesn't work for me.
I've also gone and implemented a converter and tried setting the row height like so:
<RowDefinition Height="{Binding Source={DynamicResource RowHeight}, Converter={StaticResource TestConverter}}"/>
But that only sets the height the first time, there are no subsequent changes.
Am I misunderstanding how binding and dynamic resources work? Or is this a bug in Xamarin?
I've figured out workarounds for this issue but would like it to work as I have it in the question.

If you want to set the
RowDefinition's Height to a Dynamic value. You can do as follows:1.created a view model
RowHeightClass2.bind the properties in
MainPage.xamlas follows:3.MainPage.xaml.cs
Note:
I added two properties
RowFirstHeightandRowSecondHeightand implemented interfaceINotifyPropertyChangedfor this view model, if we change the value of above properties, the UI will update automatically.