Gold.strike
Gold.strike

Reputation: 1287

Xamarin.Forms : how to reproduce this UI that combines embedded layouts

I try to reproduce this UI on a page: Expeceted UI

The page contains:

I'm already able to display the image of the main item, and the other items with a XAML that looks like this:

<ScrollView>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="450" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <!-- Main item  -->
        <StackLayout MinimumHeightRequest="450" HeightRequest="450">
            <ffil:CachedImage Source="{Binding MainProduct.Icon}"      
                              MinimumHeightRequest="450" HeightRequest="450" 
                              Aspect="AspectFill"/>
        </StackLayout>

        <!-- Other items -->
        <!-- through the use of 2 Repeaters -->
    </Grid>
</ScrollView>

But when I try to add the content that is displayed on the main item's Image, I encounter a problem: the page is no longer displayed cause the app encounters an error when the page is instancied.

I've added a secondary Grid that is placed in the first Row of the existing Grid, cause I hoped that shoud help me to show the related content of the main item on the Image:

<ScrollView>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="450" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <!-- Main item  -->
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="**" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>                   
            <StackLayout MinimumHeightRequest="450" HeightRequest="450"
                        Grid.ColumnSpan="2" Grid.RowSpan="2">
                <ffil:CachedImage Source="{Binding MainProduct.Icon}" 
                                  MinimumHeightRequest="450" HeightRequest="450" 
                                  Aspect="AspectFill"/>
            </StackLayout>
            <Frame BackgroundColor="Black"
                   Opacity="0.75"
                   Margin="10"
                   VerticalOptions="End" HorizontalOptions="End"
                   Grid.Column="1" Grid.Row="1">
                <StackLayout>
                    <Label Text="{Binding MainProduct.Title}" 
                           HorizontalOptions="StartAndExpand" VerticalTextAlignment="Center"/>
                    ...
                </StackLayout>
            </Frame>
        </Grid>

        <!-- Other items -->
        <!-- through the use of 2 Repeaters -->
    </Grid>
</ScrollView>

What's wrong in my XAML? Is there a better way to achieve this through RelativeLayout or AbsoluteLayout?

Edit

the error is the following:

{System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.FormatException: One of the identified items was in an invalid format. at Xamarin.Forms.GridLengthTypeConverter.ConvertFromInvariantString (System.String value) [0x000a0] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\GridLengthTypeConverter.cs:24 at MyProjectTablet.Views.ListProductPage.InitializeComponent () [0x00012] in C:\Projets\MyProject\MyProjectNewUi\DevMyProjectNewUi\tablet\MyProjectTablet\MyProjectTablet\obj\Debug\MyProjectTablet.Views.ListProductPage.xaml.g.cs:21 at MyProjectTablet.Views.ListProductPage..ctor () [0x00008] in C:\Projets\MyProject\MyProjectNewUi\DevMyProjectNewUi\tablet\MyProjectTablet\MyProjectTablet\Views\ListProductPage.xaml.cs:24 at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&) at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in <657aa8fea4454dc898a9e5f379c58734>:0 --- End of inner exception stack trace --- at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00017] in <657aa8fea4454dc898a9e5f379c58734>:0 at System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic) [0x000a8] in <657aa8fea4454dc898a9e5f379c58734>:0 at System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x00009] in <657aa8fea4454dc898a9e5f379c58734>:0 at System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x00027] in <657aa8fea4454dc898a9e5f379c58734>:0 at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) [0x0002c] in <657aa8fea4454dc898a9e5f379c58734>:0 at System.Activator.CreateInstance (System.Type type) [0x00000] in <657aa8fea4454dc898a9e5f379c58734>:0 at MobileCommon.Services.NavigationService.CreatePage (MobileCommon.Services.PageType pageType, System.Object parameters) [0x00053] in C:\Projets\MyProject\MyProjectNewUi\DevMyProjectNewUi\mobile\MobileCommon\Services\NavigationService.cs:118 }

I don't understand why I get an exception related to the GridLengthTypeConverter...

Upvotes: 1

Views: 335

Answers (1)

Martin Zikmund
Martin Zikmund

Reputation: 39102

The problem is in fact very different - you accidentally used ** instead of * as in one of the ColumnDefinitions:

<ColumnDefinition Width="**" />

To illustrate how I noticed this is by looking at the exception stack trace. You can see the second line says Xamarin.Forms.GridLengthTypeConverter.ConvertFromInvariantString (System.String value). This points you to the source of the error quite well.

To get a n:1 ratio of column sizes, you need to write n* where n is a number, instead of **, , like:

<ColumnDefinition Width="2*" />

Upvotes: 1

Related Questions