3

I'm trying to achieve dynamic row height in CollectionView control, so that when ever I have more text for a particular property it will extend the height of the frame automatically.

I have tried with ListView as well using HasUnEvenRow property "true" but with that also it's not working.

Here is my code:

<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
    <Grid RowDefinitions="*,60" BackgroundColor="{StaticResource PageBackgroundColor}" Padding="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <CollectionView Grid.Row="0" HorizontalOptions="Fill" VerticalOptions="Fill"
                        ItemsSource="{Binding Inspections}"
                        VerticalScrollBarVisibility="Always"
                        ItemsLayout="VerticalList" ItemSizingStrategy="MeasureAllItems">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Frame Padding="15" HasShadow="False">
                        <Grid HorizontalOptions="Fill"
                                VerticalOptions="Fill"
                                BackgroundColor="White"
                                RowSpacing="25"
                                RowDefinitions="Auto,Auto,Auto"
                                ColumnDefinitions="*,Auto">
                            <StackLayout
                                Orientation="Horizontal"
                                Grid.Row="0"
                                Grid.Column="0">
                                <Label Text="{Binding Path=BusinessName}"
                                        Style="{StaticResource LabelTitleStyle}" />
                                <Grid Padding="15,0,0,0">
                                    <baseChip:Chip
                                        HorizontalOptions="Fill" VerticalOptions="Fill"
                                        Style="{StaticResource ChipContainer}"
                                        HasShadow="False"
                                        BackgroundColor="{Binding Path=ChipBackgroundColor}">
                                    </baseChip:Chip>
                                    <Label
                                        Text="{Binding Path=ChipText}" 
                                        Style="{StaticResource ChipLabel}"
                                        HorizontalOptions="CenterAndExpand"
                                        VerticalOptions="CenterAndExpand"
                                        TextColor="{Binding Path=ChipTextColor}"/>
                                </Grid>
                            </StackLayout>

                            <Image
                                Grid.Row="0"  
                                Grid.Column="1"
                                HorizontalOptions="End"
                                VerticalOptions="Center"
                                Aspect="AspectFit">
                                <Image.Source>
                                    <FontImageSource Glyph="{x:Static helper:MaterialFontHelper.FilePdfBox}"
                                                        Color="{StaticResource DarkGray}"
                                                        Size="20"
                                                        FontFamily="MaterialDesignIcons"/>
                                </Image.Source>
                            </Image>


                            <Grid Grid.Row="1"
                                    Grid.Column="0"
                                    Grid.ColumnSpan="2"
                                    RowDefinitions="Auto, Auto"
                                    ColumnDefinitions="*, *">

                                <Label
                                    Grid.Row="0"
                                    Grid.Column="0"
                                    Text="Inspection Type"
                                    Style="{StaticResource LabelKeyStyle}" />

                                <Label
                                    Grid.Row="1"
                                    Grid.Column="0"
                                    Text="ksd kahdkahd kahd kahd  aojsoiud aasjlj sdlkja dlkja da asdadas  alsajdlaksjdlajd  alsjdalkjd alksjd sa"
                                    Style="{StaticResource LabelValueStyle}" />

                                <Label
                                    Grid.Row="0"
                                    Grid.Column="1"
                                    Text="Primary Inspector"
                                    Style="{StaticResource LabelKeyStyle}" />

                                <Label
                                    Grid.Row="1"
                                    Grid.Column="1"
                                    Style="{StaticResource LabelValueStyle}" >
                                    <Label.FormattedText>
                                        <FormattedString>
                                            <Span Text="{Binding Path=InspectorFirstName}"/>
                                            <Span Text=" "/>
                                            <Span Text="{Binding Path=InspectorLastName}"/>
                                        </FormattedString>
                                    </Label.FormattedText>
                                </Label>
                            </Grid>

                            <Grid Grid.Row="2"
                                    Grid.Column="0"
                                    Grid.ColumnSpan="2"
                                    RowDefinitions="*, *"
                                    ColumnDefinitions="*, *">

                                <Label
                                    Grid.Row="0"
                                    Grid.Column="0"
                                    Text="Scheduled Date"
                                    Style="{StaticResource LabelKeyStyle}" />

                                <Label
                                    Grid.Row="1"
                                    Grid.Column="0"
                                    Text="{Binding Path=ScheduledStartDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
                                    Style="{StaticResource LabelValueStyle}" />

                                <Label
                                    Grid.Row="0"
                                    Grid.Column="1"
                                    Text="Completed Date"
                                    Style="{StaticResource LabelKeyStyle}" />

                                <Label
                                    Grid.Row="1"
                                    Grid.Column="1"
                                    Text="{Binding Path=CompletionDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
                                    Style="{StaticResource LabelValueStyle}" />
                            </Grid>
                        </Grid>
                    </Frame>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <StackLayout
                Grid.Row="1"
                VerticalOptions="End"
                HorizontalOptions="FillAndExpand"
                BackgroundColor="{StaticResource White}">
            <controlTemplate:BeginInspectionContentView></controlTemplate:BeginInspectionContentView>
        </StackLayout>
    </Grid>
</StackLayout>

Output & expected output image attached here: enter image description here

How to achieve dynamic height for this UI? Any help or suggestions are welcome.

Florian
  • 1,019
  • 6
  • 22
Divyesh
  • 2,085
  • 20
  • 35
  • Your expected result only shows a single word compared to the current output, which may be confusing. Is your expectation to truncate the Label or should the View around the Label grow? You should clarify that. Also, where is the `LabelValueStyle` defined? – Julian Dec 22 '22 at 20:29
  • Not enough code to replicate it, a simple repo would be of help. As there was an issue in official repo when wrapping label text inside listview, suggestion is to remove nested `Grid` and set a `WidthRequest` of Label to identify the issue first. (And some elements could be simplified as well) – Shaw Dec 22 '22 at 20:59
  • The code that sets new text, should be run on MainThread (UI thread), to ensure Maui/Xamarin updates UI - is it? Can test whether it isn't: `if (!MainThread.IsMainThread) throw new InvalidProgramException("Not on MainThread);`. – ToolmakerSteve Dec 23 '22 at 03:02
  • @ewerspej LabelValueStyle is style defined for label, nothing else. – Divyesh Dec 23 '22 at 08:29
  • @Shaw it's CollectionView not ListView. And yes I want to grow the height of label dynamically and also the entire fram. – Divyesh Dec 23 '22 at 08:30

2 Answers2

0

There are three solutions to this problem:

  1. You can change CollectionView to FlexLayout with BindableLayout.ItemsSource and BindableLayout.ItemTemplate. Then you don't need to set Height for item or FlexLayout because all are dynamic.
  2. You can set a value to collectionView.HeightRequest using MVVM. When item increase, the height will increase as well. For more details about this solution, you may refer to the link.
  3. You can use CollectionView.Behaviors to calculate the Height of every item to increase the height of ContentView. For more details about this solution, you may refer to the link.
Liyun Zhang - MSFT
  • 8,271
  • 1
  • 2
  • 14
  • None of these 3 works for me, if it does work for you please share it. I have figured out the actual issue, Label control's height is not increasing dynamically according to content. That's why it's not working. – Divyesh Dec 23 '22 at 10:57
  • Did you try to set the padding property of the label? And have you achieved some effect now? – Hongxin Sui-MSFT Dec 26 '22 at 01:33
  • Yes, tried padding but that also not works. – Divyesh Dec 26 '22 at 10:20
0

You have Grid. With StackLayout. With Grid. With Small Grids inside it.

I will put aside for now, that this is extremely bad for rendering. (It is serious problem however...)

None of the expected output justify this organization.

If you need for element to occupy 2 columns, you can use columns span 2. Before anything else, please combine all 4 grids in a single grid.

After you are done with that, limit your VisualElements height, or, even better, limit the content you are putting in them. (Because cut content looks bad. You should be using something like "show more" link, that opens popup or whatever).

If you have any questions, please ask.

Edit: Let me clarify:

You have the same Grid code. Most important part - columns are * , * , and rows are auto height. And every 2 rows, you create another GRID, that is copy of the first GRID.

This is extremely counterproductive.

Also, just because you can do something, and it is "working in xamarin", it doesn't mean that you should do it.

First, put everything in the same grid, instead of nesting it and copying grids, then you can start working on CLIP/Height limit/etc.

(Recommending you to test it on IOS, because once you get it running fine there, it is much easier to fine-tune it for other platforms, than the other way around.)

H.A.H.
  • 2,104
  • 1
  • 8
  • 21
  • This does not make any sense to me, because I have implemented the same logic in Xamarin.Forms. In that, it works fine. Have you tried the solution you suggested? If not please give it try, you will notice what I have mentioned. – Divyesh Dec 23 '22 at 15:16
  • @Divyesh_08 I clarified a bit what you have to do. It is tested, I work mostly with Grids in my projects. – H.A.H. Dec 25 '22 at 06:59
  • Agree, you have worked with Grids, but that would be in Xamarin.Forms and not in .Net MAUI. Both are different. – Divyesh Dec 25 '22 at 13:47