Home > Back-end >  Using BindingContext within Border (C# MAUI, appliable to Xamarin/WPF)
Using BindingContext within Border (C# MAUI, appliable to Xamarin/WPF)

Time:12-28

I've been struggling with getting Binding to work within a Border. When I try to bind something outside the Border, it works wonderfully, but I can't get it to work within the Border.

Code here of what works:

<DataTemplate x:Key="TaskTemplate">
        <GridLayout
            ColumnDefinitions="*"
            >
            <Label Text={Binding Path=TestText}/>
        </GridLayout>
    </DataTemplate>

This code displays the text properly.

What does not and what I need to get to work:

<DataTemplate x:Key="TaskTemplate">
        <GridLayout
            ColumnDefinitions="*"
            >
            
            <Border
                GridLayout.Column="0"
                BackgroundColor="{StaticResource MidBackgroundColor}"
                StrokeThickness="1"
                Stroke="Transparent"
                HorizontalOptions="Center">

                <Border.StrokeShape>
                    <RoundRectangle CornerRadius="30"/>
                </Border.StrokeShape>


                <Label 
                    Text="{Binding Path=TestText}"/>
            </Border>
        </GridLayout>
    </DataTemplate>

This code shows it as empty.

From what I've understood so far, the Border takes away the Context and I've tried numerous things off of other threads to get it to work, but since I'm quite new, I'm struggling to find out how it works exactly.

Thanks in advance!

EDIT: I've already tried replacing the Binding with plain text and that works just fine, so it's not that a Label within a Border would be invisible.

I want to clarify that the aforementioned Text property is not actually the Label's or Border's Text property, but a Text property of a bounded object. Renamed it for clarity above to TestText.

This code shows proper text:

        <GridLayout
            ColumnDefinitions="*"
            >
            
            <Border
                GridLayout.Column="0"
                BackgroundColor="{StaticResource MidBackgroundColor}"
                StrokeThickness="1"
                Stroke="Transparent"
                HorizontalOptions="Center">

                <Border.StrokeShape>
                    <RoundRectangle CornerRadius="30"/>
                </Border.StrokeShape>


                <Label 
                    Text="Testing text."/>
            </Border>
        </GridLayout>
    </DataTemplate>

The desired result is this: https://i.stack.imgur.com/wUdGD.jpg

But instead of the hard-coded text, it should Bind text of another object. This shouldn't be an issue of other code, since it works just fine if I write the code outside the Border.

EDIT2: Including all the other code.

This is the Page that displays everything.

TasksPage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    <ContentPage.Resources>
        <ResourceDictionary Source="/Views/ViewTask.xaml"/>
    </ContentPage.Resources>

    <GridLayout RowDefinitions="*">
        <GridLayout
            
            GridLayout.Row="0"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand">
            <StackLayout Margin="5,5,5,0">
                <CollectionView x:Name="TasksCollection"
                                ItemsSource="{Binding Tasks}"
                                ItemTemplate="{StaticResource TaskTemplate}">
                </CollectionView>
            </StackLayout>
        </GridLayout>
    </GridLayout>
</ContentPage>

TasksPage.xaml.cs:

public partial class TasksPage : ContentPage
{
    public TasksPage()
    {
        InitializeComponent();

        BindingContext = new TaskViewModel();
    }
}

This is the itemtemplate for that collection. ViewTask.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

    <DataTemplate x:Key="TaskTemplate">
        <GridLayout
            ColumnDefinitions="*">

            <Border
                GridLayout.Column="0"
                BackgroundColor="{StaticResource MidBackgroundColor}"
                StrokeThickness="1"
                Stroke="Transparent"
                HorizontalOptions="Center">

                <Border.StrokeShape>
                    <RoundRectangle CornerRadius="30"/>
                </Border.StrokeShape>

                <Label GridLayout.Column="0" 
                       GridLayout.Row="0"
                       Text="{Binding TaskText}" />
            </Border>
        </GridLayout>
    </DataTemplate>
</ResourceDictionary>

The ViewModel just has an ObservableCollection, which works just fine. So all the items actually populate the DataTemplate, it's just that the DataTemplate only shows Binded properties if it's not within a Border.

CodePudding user response:

Someone else has also seen this as a bug. Lester Moreno's comment on blog announcing maui preview 9.

For now, you can simulate Border by using "Frame-inside-Frame":

<!-- Without Grid, the Frame takes the whole width. -->
<!-- To have multiple buttons in one row, use more Grid columns. -->
<!-- Border will be more convenient once it works. -->
<Grid ColumnDefinitions="Auto,*">
    <!-- "Padding 6" of outer frame determines how thick the Border color is. -->
    <Frame HasShadow="False" CornerRadius="18" Padding="6" BackgroundColor="#F69927">
        <!-- "Padding 2" of inner frame is white space surrounding the label. -->
        <Frame HasShadow="False" CornerRadius="12" BackgroundColor="White" Padding="6,2">
            <Label Text="{Binding LabelText}" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"
           TextColor="Blue"/>
        </Frame>
    </Frame>
</Grid>
  • Related