Home > other >  .NET MAUI multibinding to XAML and view model
.NET MAUI multibinding to XAML and view model

Time:10-27

In my .NET MAUI code-behind file for my MainPage, I would like to multi-bind to an element of my ViewModel as well as to the width and height of a grid defined in XAML.
The aim is to have the font in each grid cell auto-resize to the cell and also respects an "is text small" boolean.

The problem seems to be, that the binding to "ScreenGrid.Height" is not resolved correctly
(the MultiValueConverter only receives an array filled with null).

ScreenGrid is defined in Xaml.
Resolving only the first of the 3 binding works as expected.
Setting the BindingContext of label to ScreenGrid does not work.

Are there any apparent mistakes or rules that I'm not aware of?

XAML:

<ContentPage [...]
    xmlns:viewmodels="clr-namespace:Renderer.ViewModels"
    x:Class="Renderer.MainPage"
    x:DataType="viewmodels:CduViewModel">
    <AbsoluteLayout>
        <!-- Screen -->
        <Grid x:Name="ScreenGrid"
            RowDefinitions="*, *, *, *, "
            ColumnDefinitions="*,*,*,*,*,*,*,*,"
            [...]>
        </Grid>
    </AbsoluteLayout>
</ContentPage>
public partial class MainPage : ContentPage
{
    public MainPage(ICduViewModel viewModel)
    {
        InitializeComponent();
        this.ViewModel = viewModel;

        AddScreenCells(); //Set up "Screen"
    }

    public void AddScreenCells()
    {
        var frameConverter = new Converters.FrameToFontSizeConverter();

        for (int row = 0; row < ScreenGrid.RowDefinitions.Count; row  )
        {
            for (int col = 0; col < ScreenGrid.ColumnDefinitions.Count; col  )
            {
                //Label
                Label label = new()
                {
                    FontAutoScalingEnabled = false
                };

                label.SetBinding(Label.FontSizeProperty, new MultiBinding
                {
                    Bindings = new Collection<BindingBase>
                    {
                        //This binding works, if used seperately
                        new Binding($"{nameof(CduViewModel.Screen)}[{row}].{nameof(CduText.Sizes)}[{col}]"),
                    
                        //These bindings only work when setting the BindingContext to ScreenGrid, which kills the binding above.
                        new Binding($"{nameof(ScreenGrid)}.{nameof(ScreenGrid.Height)}"),
                        new Binding($"{nameof(ScreenGrid)}.{nameof(ScreenGrid.Width)}"),
                        },
                        Converter = frameConverter
                    });

                    ScreenGrid.Add(label, col, row);
                }
            }
        }
    }
}

CodePudding user response:

Set "source:" parameter of each ScreenGrid Binding:

new Binding($"{nameof(ScreenGrid)}.{nameof(ScreenGrid.Height)}",
        source: ScreenGrid)

This makes ScreenGrid the BindingContext of that Binding.

I did not test; maybe remove {nameof(ScreenGrid)}. from the path parameter.

  • Related