Search code examples
c#androidxamlxamarin.formscontentpresenter

Xamarin forms contentpresenter goes in wrong row and empty on phone


I'm having a go at Xamarin Forms trying to create my custom 'GroupBox' control which is a just a grid with two rows. The first row should just show a box with a header . The header has a background rectangle with a label. The second row shows the content via ContentPresenter the content goes below in the second row.

I believe I've done the XAML correctly, this is how I'd do it in WPF, it shows in the GroupBox.xaml Forms Previewer fine, but when I add it into the main page, the content of the Groupbox goes into the first row (the header) instead of the second for some reason within the Previewer.

the content is going into the header

furthermore, when I attempt to run on an android phone, it just looks like this:

the group boxes are blank frames with no background colour or text

the group boxes are blank frames with no background colour or text

This is the code of the GroupBox 'user control'

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XForms.GroupBox">

    <Grid.RowDefinitions>
        <RowDefinition Height="0.2*"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>

    <Frame Grid.Row="0" Grid.RowSpan="2" Margin="1" OutlineColor="AliceBlue"/>

    <BoxView Grid.Row="0" BackgroundColor="Red" Margin="1"/>

    <Label Grid.Row="0" TextColor="White" Text="Label!" Margin="2" />

    <Grid Grid.Row="1">   
        <ContentPresenter/>
    </Grid>

</Grid>

This code is in the main form:

<?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:XForms;assembly=XForms"
                 x:Class="XForms.MainPage">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <Grid Grid.Column="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*"/>
                    <RowDefinition Height="1*"/>
                    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>

                <local:GroupBox Grid.Row="0">
                    <Label Text="I'm some content 1"/>
                </local:GroupBox>

                <local:GroupBox Grid.Row="1">
                    <Label Text="I'm some content 2"/>
                </local:GroupBox>

                <local:GroupBox Grid.Row="2">
                    <Label Text="I'm some content 3"/>
                </local:GroupBox>
            </Grid>
        </Grid>
    </ContentPage>

in the main page XAML I can add a grid row to the label, even though there is no grid in the content, and it will work in the previewer -- but it's still blank on the phone (Which is most important).

  <local:GroupBox Grid.Row="0">
                    <Label Text="I'm some content 1" Grid.Row="1"/>
                </local:GroupBox>

Solution

  • I don't know what is the Frame for, but it is currently covering the BoxView and labels and thus made them invisible. Comment out the Frame and you will see the labels and BoxView again.

    I believe I've done the XAML correctly, this is how I'd do it in WPF, it shows in the GroupBox.xaml Forms Previewer fine, but when I add it into the main page, the content of the Groupbox goes into the first row (the header) instead of the second for some reason within the Previewer.

    ContentPresenter doesn't work like that.In Xamarin.Forms, it is generally used in ControlTemplate. For usage of ContentPresenter, please refer to this blog.

    In your case, if you want to ContentPresenter to work. Instead of using Grid for GroupBox, you can use ContentView for GroupBox like below:

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class GroupBox : ContentView
    {
        public GroupBox()
        {
            InitializeComponent();
        }
    }
    

    GroupBox.xaml:

    <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Demo.GroupBox">
    <ContentView.ControlTemplate>
        <ControlTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.2*"/>
                    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>
                <!--<Frame Grid.Row="0" Grid.RowSpan="2" Margin="1" OutlineColor="AliceBlue"></Frame>-->
                <BoxView Grid.Row="0" BackgroundColor="Red" Margin="1"  />
                <Label Grid.Row="0" TextColor="White" Text="Label!" Margin="2" />
                <Grid Grid.Row="1">
                    <ContentPresenter/>
                </Grid>
            </Grid>
        </ControlTemplate>
    </ContentView.ControlTemplate>