CarouselView dynamic height

322 Views Asked by At

I have now spent like forever trying to figure out what I thought would be the easiest and most obvious functionality of the carouselView: Height according to content.

No matter what I do, the height of the CarouselView is the screen height. I do not want that as my content is dynamic text which can have different sizes. The page consists of a static top, the contentView and a static bottom of data.

I know that it might actually be the way it works (https://github.com/xamarin/Xamarin.Forms/issues/8640) which to me makes the carouselView totally useless unless using static images of a static height.

However I am still hoping, that I am wrong. Is there a way to achieve what I want?

Thank you very much.

UPDATE: The issue might be, that I want the CarouselView inside a ScrollView, as I want it to be a part of the page. Inside a scrollView the CarouselView will get the height of the page and not the content. Can that be solved?

<StackLayout>
    <Label Text="Hello!" />
    <CarouselView ItemsSource="{Binding Challenge.ChallengeParts}" Position="{Binding PageCarouselPosition}" Grid.Row="0" Grid.Column="0">
        <CarouselView.ItemTemplate>
            <DataTemplate>
                <StackLayout BackgroundColor="red">
                    <Label Text="Hello! inside CarouselView" />
                </StackLayout>
            </DataTemplate>
        </CarouselView.ItemTemplate>
    </CarouselView>
    <Label Text="Hello!" />
</StackLayout>

UPDATE 2: This will be some of the desired content of the CV:

<StackLayout BackgroundColor="green">
  <Grid>
      <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="20" />
      </Grid.ColumnDefinitions>
      <Label Text="Vis regler fra video" FontAttributes="Bold" Grid.Column="0" Grid.Row="0" />
      <Label Text="{Binding Source={x:Reference thisPage}, Path=BindingContext.ShowRules,Converter={StaticResource CaretConverter}}" FontFamily="{StaticResource FontAwesomeSolid}" Grid.Column="1" Grid.Row="0" HorizontalTextAlignment="End" />
  </Grid>

  <StackLayout IsVisible="{Binding Source={x:Reference thisPage}, Path=BindingContext.ShowRules}">
      <Grid Margin="20, 0, 0, 0">
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="50" />
              <ColumnDefinition Width="*" />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition Height="Auto" />
              <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
          <!--Antal spillere-->
          <StackLayout Orientation="Horizontal" Grid.Column="0" Grid.Row="0">
              <Label Text="&#xf183;" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="30" />
              <Label Text="&#xf182;" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="30" />
          </StackLayout>
          <StackLayout Spacing="0" Grid.Column="1" Grid.Row="0">
              <Label Text="Antal spillere:" FontAttributes="Bold" FontSize="Micro" />
              <Label Text="{Binding NumPlayers}" FontSize="Micro" />
          </StackLayout>
          <!--Nødvendigt udstyr-->
          <StackLayout Orientation="Horizontal" Grid.Column="0" Grid.Row="1">
              <Label Text="&#xf45d;" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="30" />
          </StackLayout>
          <StackLayout Spacing="0" Grid.Column="1" Grid.Row="1">
              <Label Text="Nødvendigt udstyr:" FontAttributes="Bold" FontSize="Micro" />
              <StackLayout BindableLayout.ItemsSource="{Binding NeededAccesories}" Spacing="0">
                  <BindableLayout.ItemTemplate>
                      <DataTemplate>
                          <Label Text="{Binding .}" FontSize="Micro" />
                      </DataTemplate>
                  </BindableLayout.ItemTemplate>
              </StackLayout>
          </StackLayout>
          <!--Regler-->
          <StackLayout Orientation="Horizontal" Grid.Column="0" Grid.Row="2">
              <Label Text="&#xf46d;" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="30" />
          </StackLayout>
          <StackLayout Grid.Column="1" Grid.Row="2">
              <Label Text="Regler:" FontAttributes="Bold" FontSize="Micro" />
              <StackLayout BindableLayout.ItemsSource="{Binding Rules}" Spacing="0">
                  <BindableLayout.ItemTemplate>
                      <DataTemplate>
                          <Label Text="{Binding .}" FontSize="Micro" />
                      </DataTemplate>
                  </BindableLayout.ItemTemplate>
              </StackLayout>
          </StackLayout>
            <Frame
              BorderColor="Transparent"
              HasShadow="false" 
              BackgroundColor="Transparent"
              Padding="0"
              CornerRadius="0"
              IsVisible="{Binding HasTopImages}">
              <grial:Repeater
                  Grid.Row="0"
                  ItemsSource="{ Binding Source={x:Reference thisPage}, Path=BindingContext.Gallery }"
                  Orientation="Horizontal"
                  HeightRequest="350"
                  Spacing="15"
                  ItemSize="350"
                  ScrollPadding="20,0"
                  ScrollBarVisibility="Never"
                  >
                  <grial:Repeater.ItemTemplate>
                      <DataTemplate>
                          <local:FullHeaderArticleGalleryItemTemplate />
                      </DataTemplate>
                  </grial:Repeater.ItemTemplate>
              </grial:Repeater>
          </Frame>
      </Grid>
  </StackLayout>

UPDATE 3: I have tried to calculate the heights as suggested. It works... almost. I can resize to correct sizes with this piece of code:

        private void UpdateCarouselViewHeight()
        {
            var cvVisibleViews = cv.VisibleViews;
            if(cvVisibleViews.Count > 0)
            {
                //cv.HeightRequest = 1;
                var rulesStack = cvVisibleViews[0].FindByName<StackLayout>("showRulesStack");
                var toggleShowRules = cvVisibleViews[0].FindByName<StackLayout>("toggleShowRules");
                var showRulesText = cvVisibleViews[0].FindByName<Label>("showRulesText");

                double height = 0;
                height = height + toggleShowRules.Height;
                height = height + showRulesText.Height;
                if (rulesStack.IsVisible && rulesStack.Height > -1)
                {
                    height = height + rulesStack.Height;
                }
                cvVisibleViews[0].HeightRequest = height;
                cv.HeightRequest = height;
            }
        }
0

There are 0 best solutions below