Home > other >  How to set flipview height based on content inside
How to set flipview height based on content inside

Time:11-02

I need to set flipview height based on content inside.It should be of the largest element. flipview contains two textblocks in which the text can be of varying size . I tried the following

Mainpage.xaml excerpt

 <Page.DataContext>
    <local:Msg/>
</Page.DataContext>


<Grid Background="LightBlue">
    <Grid.RowDefinitions>

        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>

    </Grid.RowDefinitions>

    <!--<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">-->
    <FlipView  x:Name="flipView1" Grid.Row="0"  ItemsSource="{Binding CustomSearchResults}" Padding="20"
          BorderBrush="Black" Background="#DEDEDE" BorderThickness="1"  VerticalAlignment="Stretch" >
        <FlipView.ItemTemplate>
            <DataTemplate>
                
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition  Height="Auto"/>
                    </Grid.RowDefinitions>
                    
                    <TextBlock   Grid.Row="0" Text="{Binding Text1}" FontFamily="Segoe UI"   TextWrapping="WrapWholeWords"
                           TextTrimming="CharacterEllipsis" Margin="0,0,0,20"       />

                    <TextBlock Grid.Row="1" Text="{Binding Text2}" FontFamily="Segoe UI" TextWrapping="WrapWholeWords"
                               TextTrimming="CharacterEllipsis"  
                                   />
                    
                </Grid>
            </DataTemplate>
        </FlipView.ItemTemplate>
    </FlipView>
    <!--</ScrollViewer>-->
</Grid>

datacontext class excerpt

     public class CustomSearchResult
    {
        public string Text1 { get; set; }
        public string Text2 { get; set; }
    }
    public class Msg
    {

        public Msg()
        {
            CustomSearchResults = new List<CustomSearchResult>();
            CustomSearchResults.Add(new CustomSearchResult
            {
                Text1 = "Hardware Trends in 2021 - Online Computer Tips....",
                Text2 = @"Famous chipmaker AMD developed a few new products. According to the latest rumors, along with the third-generation EPYC server processors, a brand new product Ryzen 5000,
                        desktop CPU based on Zen 3 architecture will be only the first of its kind, released in 2021."
            });
            CustomSearchResults.Add(new CustomSearchResult
            {
                Text1 = "What are the latest trends in hardware technology? – AnswersToAll",
                Text2 = @"What are the latest trends in hardware technology? Current trends in hardware and software include the increasing use of reduced instruction-set computing, migration to the UNIX operating system, the development of large software libraries, 
                           microprocessor-based smart terminals that allow remote validation of data, speech synthesis and recognition, application …"
            });

            CustomSearchResults.Add(new CustomSearchResult
            {
                Text1 = "Kitchen cabinet hardware 2021-2022: latest trends and stylish …",
                Text2 = @"One of the 2022 kitchen trends is the geometric forms. We suggest you incorporate this idea into your kitchen cabinet hardware. It will offer the decor 
                        a point of interest and emphasize the sharp lines of the cabinets. Furthermore, this design will integrate perfectly in any style and enrich it with stability. Large Text
 Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text Large Text
 Large Text"
            });
        }

        public List<CustomSearchResult> CustomSearchResults { get; set; }


    }

flipview app screenshot enter image description here

The flip view height should be shrinked to the largest content . I tried wrapping scrollviewer around flipview with no luck. I applied the arttribute verticalalignment=stretch with no luck. I heard that measure and arrange phase such as measureoverride() are used in customizing the layout ,but I am not sure which event need to get hooked for that

CodePudding user response:

You could achieve this by calculating all the FlipViewItem height in the loaded event and then changing the FlipView height.

First of all, you have to modify your Xaml a little bit. The default ItemsPanel of the FlipView is VirtualizingStackPanel which uses Virtualizing. It means the FlipView will create only a few itemcontainers and reuse these containers. This will stop us from finding all the items and getting the height. So we just need to change the ItemsPanel to StackPanel.

Then you need to add the padding to the Gird inside the item template instead of adding the padding to the FlipView.

At last, you need to add a name to the TextBlock in order to find them later in the code behind.

Here is the modified code:

      <!--<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">-->
    <FlipView x:Name="flipView1" Grid.Row="0"  ItemsSource="{Binding CustomSearchResults}"
      BorderBrush="Black" Background="#DEDEDE" BorderThickness="1"  VerticalAlignment="Stretch" >
        <FlipView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel AreScrollSnapPointsRegular="False" Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </FlipView.ItemsPanel>
        <FlipView.ItemTemplate>
            <DataTemplate>

                <Grid Padding="20" >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition  Height="Auto"/>
                    </Grid.RowDefinitions>

                    <TextBlock x:Name="FirstTextBlock"  Grid.Row="0" Text="{Binding Text1}"  FontFamily="Segoe UI"   TextWrapping="WrapWholeWords"
                       TextTrimming="CharacterEllipsis" Margin="0,0,0,20"       />

                    <TextBlock x:Name="SecondTextBlock" Grid.Row="1" Text="{Binding Text2}" FontFamily="Segoe UI" TextWrapping="WrapWholeWords"
                           TextTrimming="CharacterEllipsis"  
                               />

                </Grid>
            </DataTemplate>
        </FlipView.ItemTemplate>
    </FlipView>
    <!--</ScrollViewer>-->

In the code behind what you need to do first is to find all the items inside the FlipView and then calculate the total height of the two TextBlock. Then find a max height over all the items.

Here is the code:

 public double TextMaxHeight { get; set; }

    public MainPage()
    {
        this.InitializeComponent();
        TextMaxHeight = 0;
        this.Loaded  = MainPage_Loaded;
    }

 private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        // get every item and Calculate it's height
        for (int i = 0; i < flipView1.Items.Count; i  )
        {
            var item = flipView1.Items[i];
            // get item container
            var _Container = flipView1.ContainerFromItem(item);
            // find the first textblock
            var _FirstBlock = (TextBlock)FindMyChildByName(_Container, "FirstTextBlock");
            var size = _FirstBlock.ActualHeight;
            // find the second textblock
            var _SecondBlock = (TextBlock)FindMyChildByName(_Container, "SecondTextBlock");
            var size2 = _SecondBlock.ActualHeight;

            //check the max height over all the items
            TextMaxHeight = TextMaxHeight > size   size2 ? TextMaxHeight : size   size2;

        }
        // change flipview's height.  40 for padding and 20 for the first textblock margin
        flipView1.Height = TextMaxHeight   60;
    }

    public static DependencyObject FindMyChildByName(DependencyObject parant, string ControlName)
    {
        int count = VisualTreeHelper.GetChildrenCount(parant);

        for (int i = 0; i < count; i  )
        {
            var MyChild = VisualTreeHelper.GetChild(parant, i);
            if (MyChild is FrameworkElement && ((FrameworkElement)MyChild).Name == ControlName)
                return MyChild;

            var FindResult = FindMyChildByName(MyChild, ControlName);
            if (FindResult != null)
                return FindResult;
        }

        return null;
    }
  • Related