Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto Height in combination with MaxHeight

Tags:

c#

wpf

xaml

I am facing a problem with setting the following xaml layout:

RowHeightAuto.xaml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="GridMaxHeight.RowHeightAuto"
    Title="RowHeightAuto" WindowState="Maximized">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" MaxHeight="200" />
    </Grid.RowDefinitions>

    <StackPanel Background="LightGray" Grid.Row="0"></StackPanel>
    <DataGrid Name="DataGrid1" Grid.Row="1" />
</Grid>

The DataGrid1 control isn't showing any scrollbars with a lot of columns and rows defined. Everything works find when I would replace the Height="Auto" with Height="*" than Horizontal and Vertical scrollbars appear like expected.

Also it works when I would declare the MaxHeight directly at the DataGrid1, but that's not really want I want.

Is this a bug that the childcontrol ignores the maxheight on setting Height="Auto" or am I propably making something wrong? Same behaviour can be reproduced with ListBox/ListView and so on, also with third party controls like ComponentOne, Telerik...

If it's a bug - do you know a workaround or have other hints for me?

Here is the code how I set the ItemsSource of the DataGrid. RowHeightAuto.xaml.cs

public partial class RowHeightAuto : Window
{
    private readonly DateTime _start;

    public RowHeightAuto()
    {
        InitializeComponent();

        DataGrid1.ItemsSource = GetTestData();

        _start = DateTime.Now;
        Dispatcher.BeginInvoke(new Action(() => MessageBox.Show((DateTime.Now - _start).TotalSeconds.ToString(CultureInfo.InvariantCulture))), DispatcherPriority.ContextIdle, null);
    }

    public static List<TestData> GetTestData()
    {
        const int maxCols = 501;
        const int maxRows = 300;

        var testDatas = new List<TestData>(maxRows);
        for (int i = 0; i < maxRows; i++)
            testDatas.Add(new TestData());

        for (int i = 0; i < maxCols; i++)
        {
            string propName = string.Format("Property{0}", AddLeadingZeros(i));

            for (int j = 0; j < maxRows; j++)
                testDatas[j][propName] = propName;
        }

        return testDatas;
    }

    private static string AddLeadingZeros(int val)
    {
        return val.ToString(CultureInfo.InvariantCulture).PadLeft(3, '0');
    }
}

public class TestData
{
    public object this[string propertyName]
    {
        get
        {
            var myType = GetType();
            var myPropInfo = myType.GetProperty(propertyName);
            return myPropInfo.GetValue(this);
        }
        set
        {
            var myType = GetType();
            var myPropInfo = myType.GetProperty(propertyName);
            myPropInfo.SetValue(this, value, null);

        }
    }

    public string Property000 { get; set; }
    public string Property001 { get; set; }
    public string Property002 { get; set; }
    public string Property003 { get; set; }
    ...
    public string Property498 { get; set; }
    public string Property499 { get; set; }
    public string Property500 { get; set; }

}
like image 302
Rand Random Avatar asked Jul 19 '13 09:07

Rand Random


People also ask

How is height auto calculated?

When using the keyword auto , height is calculated based on the elements content area unless explicitly specified. This means a value based on a percentage is still that of the elements content area.

How do I Auto adjust height in CSS?

If height: auto; the element will automatically adjust its height to allow its content to be displayed correctly. If height is set to a numeric value (like pixels, (r)em, percentages) then if the content does not fit within the specified height, it will overflow.

How do you set the maximum height on a car?

You would need a parent div of course: jsfiddle.net/fL02zufu In that case your height would be "auto" in the sense that you would inherit it from your parent div but you'd have the max-height in place.

What is the difference between height and max-height?

Main difference between is height take the space from screen even selector element is empty but max-height set the of maximum limit of height on selector element but no space will take until no content pushed inside.


1 Answers

This is exactly as you say it is.

The reason why you do not see the Scrollbar's is because even though the Grid Clip's the DataGrid, it's merely a Clip, the ActualHeight of the DataGrid is the height it would get if allowed to show all it's children. You are thus not seeing it's scrollbar's. ActualHeight is so cos it's allowed to get all the space it wants with Height="Auto" on the Grid. The reason I wouldn't call this a bug personally is cos you might desire this behavior if you want to play with the ClipToBounds property of the Grid for certain animations and this is the behavior you desire. Thinking about this, I actually think I'd call this a bug too in terms of "Not desirable functionality" than "Incorrect output"

To get the behavior your looking for,

  • Apply the MaxHeight on the DataGrid or use Grid RowDefinition.Height="*" <- both as you mentioned (Not sure why you say this is not what you want to do?)
  • Or you could also use a RelativeSourceBinding on the DataGrid

something like -

<DataGrid Name="DataGrid1" 
          Grid.Row="1"
          Height="{Binding RelativeSource={RelativeSource FindAncestor,
                           AncestorType={x:Type Grid}},
                           Path=RowDefinitions[1].ActualHeight}">

For such issues Snoop is your friend. You can easily check this behavior and realize why the scrollbar's aren't shown when you check the ActualHeight on your DataGrid using Snoop and see it allocates quite a bit more height to the child control.

like image 187
Viv Avatar answered Oct 26 '22 14:10

Viv