2

I need to compute the exact height of a RichEditBox, depending on its content. For this sake, I use the following method, which proves quite ok in any case, BUT when the text is one line!

    public static double GetElemHeight(FrameworkElement elem, double? actualWidth = null)
    {
        if (elem == null)
            return 0;

        // take note of the existing height, if any, since we have to re-establish it later:
        double currentH = elem.Height;
        if (!double.IsNaN(currentH))
            elem.Height = double.NaN;
        double totalW = (actualWidth ?? elem.Width) + elem.Margin.Left + elem.Margin.Right;

        // Measure() only works as expected in this context if the Height is NaN:
        elem.Measure(new Size(totalW, Double.PositiveInfinity));
        Size size = elem.DesiredSize;
        elem.Height = currentH; //re-establish the correct height
        return size.Height - elem.Margin.Top - elem.Margin.Bottom;
    }

Basically what happens is that for any text written in the RichEditBox, the method returns the correct height of the element. But when I have a text that covers only one line, the result is always an height that is almost the double of the correct result.

Please find here an MVC that reproduces the problem: https://github.com/cghersi/UWPExamples/tree/master/SizeOfTextBox

Any clue on what am I doing wrong?

Cristiano Ghersi
  • 1,944
  • 1
  • 20
  • 46
  • Have you tried checking the ActualHeight property? – Shawn Kendrot Sep 06 '19 at 19:51
  • Unfortunately I need this information before the first actual rendering of the element, therefore I cannot use the ActualHeight – Cristiano Ghersi Sep 06 '19 at 19:53
  • What do you need the height information for? – Shawn Kendrot Sep 06 '19 at 20:10
  • For a number of reasons, the main ones being: 1) to compute the correct height of the parent Canvas, which should grow accordingly to the user that types into the text box. 2) to define the actual correct height of other XAML components, whose size depends on the height of the text box. – Cristiano Ghersi Sep 06 '19 at 21:06
  • I ask because you might be able to accomplish your task easier by taking another approach. For example. If you want to display a number of TextBoxes, then maybe an placing them in the ItemTemplate of an ItemsControl would be better. UI Elements should rarely go into a Canvas. Maybe a StackPanel would be better? – Shawn Kendrot Sep 06 '19 at 21:29
  • Thank you Shawn, but this is part of a big project with a lot of customizations and very harsh performance requirements: it is impossible at this time to change the structure of the XAML. We just need to make the GetElemHeight() method return the correct values. – Cristiano Ghersi Sep 07 '19 at 00:54

1 Answers1

2

The default height of RichEditBox is 32px, it means when your actual height less than 32, it still displays 32. And in style, control the height of content is Border, so you should change the MinHeight of Border. In addition, you can go to generic.xaml to get the style of RichEditBox.

<Page.Resources>
        <Style TargetType="RichEditBox">
            ......
            <Setter Property="SelectionFlyout" Value="{StaticResource TextControlCommandBarSelectionFlyout}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="RichEditBox">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                ......
                            </VisualStateManager.VisualStateGroups>
                            ......
                            <Border x:Name="BorderElement" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding CornerRadius}" MinHeight="0" MinWidth="{ThemeResource TextControlThemeMinWidth}" Grid.RowSpan="1" Grid.Row="1"/>
                            ......
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Page.Resources>
Faywang - MSFT
  • 5,798
  • 1
  • 5
  • 8