Xamarin Forms Binding String Array to BindableLayout only works after Xaml Hot Reload
Asked Answered
T

2

5

I am having issues binding the values of a string[] to the DataTemplate of a BindableLayout. I have recreated the issue in the AboutPage of the Shell Flyout Template.

AboutPage.xaml

<ContentPage.BindingContext>
    <vm:AboutViewModel />
</ContentPage.BindingContext>

<StackLayout VerticalOptions="Center"
             Padding="20"
             BindableLayout.ItemsSource="{Binding Data}">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Label FontSize="Large"
                   Text="{Binding .}"
                   BackgroundColor="PowderBlue"/>
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

AboutViewModel.cs

namespace App2.ViewModels
{
    public class AboutViewModel : BaseViewModel
    {
        private string[] _data;
        public string[] Data
        {
            get
            {
                return _data;
            }
            set
            {
                if (_data != value)
                {
                    _data = value;
                    OnPropertyChanged();
                }
            }
        }
        public AboutViewModel()
        {
            Title = "About";
            Data = new string[] { "One", "Two", "Three" };
        }

    }
} 

When the page first opens, the the correct number of labels are there but without any text. Labels without text If I edit the Text="{Binding .}" the binding works after Xaml Hot Reload. Labels with text Why on earth are the strings not being displayed in the first place when they're clearly not empty or null?

Townscape answered 3/5, 2021 at 5:57 Comment(0)
T
4

I have solved this problem in an unexpected way. Simply by moving the DataTemplate into its own file, this problem goes away. Can someone please explain to me why this works? My new code produces two StackLayouts side by side, bound to the same data but only the Stackview on the right, with its DataTemplate defined elsewhere as ListItemView.xaml shows the data when the app is run. The StackView on the left has empty Labels at first, then after I delete the full-stop (.) from Text="{Binding .}" and replace it, Xaml Hot Reload runs and the strings are displayed.

ListItemView.xaml

<DataTemplate xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="App2.Views.ListItemView">
    <Label FontSize="Large"
           Text="{Binding ., Mode=OneWay}"
           BackgroundColor="PowderBlue"/>
</DataTemplate>

AboutPage.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App2.Views.AboutPage"
             xmlns:vm="clr-namespace:App2.ViewModels"
             xmlns:views="clr-namespace:App2.Views"
             Title="{Binding Title}"
             x:DataType="vm:AboutViewModel">

    <ContentPage.BindingContext>
        <vm:AboutViewModel />
    </ContentPage.BindingContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <StackLayout VerticalOptions="Center"
                     Padding="20"
                     BindableLayout.ItemsSource="{Binding Data}"
                     Grid.Column="0">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <Label FontSize="Large"
                           Text="{Binding ., Mode=OneWay}"
                           BackgroundColor="PowderBlue"/>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
        <StackLayout VerticalOptions="Center"
                     Padding="20"
                     BindableLayout.ItemsSource="{Binding Data}"
                     Grid.Column="1">
            <BindableLayout.ItemTemplate>
                <views:ListItemView />
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </Grid>
    
</ContentPage>

enter image description here

Townscape answered 3/5, 2021 at 12:13 Comment(1)
This works for me as well and it is very strange. Thanks by the way..!Gradus
H
3

I solved this in a similar way. I did create a separate DataTemplate, but not in its own file. The addition I made was to add an x:DataType attribute.

<DataTemplate x:Key="myLabel" x:DataType="x:String">
    <StackLayout>
        <Label Text="{Binding .}" />
    </StackLayout>
</DataTemplate>
Holcomb answered 10/3, 2022 at 7:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.