Search code examples
xamlxamarin.formsdata-bindingxamarin-community-toolkit

How to bind the content of a control to a property of type VIEW in XAML


I would like to make a generic settings page for my App. I have a list of different types of settings, each one corresponding to the following interface:

public interface ISettings
{
    string SectionLabel { get; }

    View SectionView  { get; }
}

Each type of settings represent a given aspect or section of the settings of the Application. The goal is to enable each type of settings to define it's own apprearance and the way to adjust it's own value.

I have a settings page with a list of all the settings : public List settingsSections { get => App.AppSettings.SettingsSections; }

In the XAML settings page, I would like to display them like this :

<StackLayout BindableLayout.ItemsSource="{Binding settingsSections, Source={x:Reference this}}" Padding="0" BackgroundColor="White">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <xct:Expander>
                <xct:Expander.Header>
                    <StackLayout Orientation="Horizontal">
                        <Image Source="{Helpers:ImageResource Images.filledDownArrow.png}" HeightRequest="{Binding Source={x:Reference heightRef}, Path=Height, Converter={Helpers:IntMultiplier Multiplier=0.99}}"
                            HorizontalOptions="Start"
                            VerticalOptions="Center">
                            <Image.Triggers>
                                <DataTrigger TargetType="Image"
                                            Binding="{Binding Source={RelativeSource AncestorType={x:Type xct:Expander}}, Path=IsExpanded}"
                                            Value="True">
                                    <Setter Property="Source"
                                        Value="{Helpers:ImageResource Images.filledRightArrow.png}" />
                                </DataTrigger>
                            </Image.Triggers>
                        </Image>
                        <Label x:Name="heightRef" Text="{Binding SectionLabel}"
                            FontAttributes="Bold"
                            FontSize="Medium" />
                    </StackLayout>
                </xct:Expander.Header>
                            
                <xct:Expander.Content="{Binding SectionView}"/>

            </xct:Expander>
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

But of course, this line don't work:

<xct:Expander.Content="{Binding View}"/>

How can I achieve my goal ? Can someone help me ? I think I can't use custom control because I should change the type of the control for every line/section of the stacklayout according to the actual type of the setting which is referred to.


Solution

  • Option 1

    You don't have to specify xct:Expander.Content at that point whatever you put there will be implicitly setting the Content property.

    Replace

    <xct:Expander.Content="{Binding SectionView}"/>
    

    With

    <ContentView Content="{Binding SectionView}"/>
    

    Option 2

    Specify it this way:

    <DataTemplate>
                <xct:Expander Content="{Binding SectionView}">
                    <xct:Expander.Header>
    ...