自动高度与MaxHeight结合使用

时间:2013-07-19 09:23:18

标签: c# wpf xaml

我在设置以下xaml布局时遇到问题:

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>

DataGrid1控件未显示任何定义了大量列和行的滚动条。 当我用高度=“*”替换高度=“自动”而不是水平和垂直滚动条看起来像预期时,一切都有效。

当我直接在DataGrid1声明MaxHeight时,它也可以工作,但这并不是我想要的。

这是一个错误,childcontrol在设置Height =“Auto”时忽略了最大高度,还是我可能犯了错误?使用ListBox / ListView等可以重现相同的行为,也可以使用ComponentOne,Telerik等第三方控件...

如果这是一个错误 - 您是否知道解决方法或对我有其他提示?

以下是我如何设置DataGrid的ItemsSource的代码。 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; }

}

1 个答案:

答案 0 :(得分:10)

这就像你说的那样。

你没有看到Scrollbar的原因是因为即使Grid Clip是DataGrid,它只是一个Clip,ActualHeight的{ {1}}是允许显示所有孩子的高度。因此,你没有看到它的滚动条。 DataGrid因此ActualHeight允许Height="Auto"获得所需的所有空间。 我之所以不会将此称为个人错误的原因是因为如果您想要使用Grid的{​​{1}}属性来播放某些动画,这可能是您想要的行为希望。考虑到这一点,我实际上认为我称之为“不理想的功能”而不是“不正确的输出”

要获得您所寻找的行为,

  • ClipToBounds上应用Grid或使用网格MaxHeight&lt; - 如您所述(不确定为什么您说这不是您想要做的?)
  • 或者您也可以在DataGrid
  • 上使用RowDefinition.Height="*"

之类的东西 -

RelativeSourceBinding

对于此类问题 Snoop 是您的朋友。您可以轻松检查此行为,并在使用Snoop检查DataGrid上的<DataGrid Name="DataGrid1" Grid.Row="1" Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=RowDefinitions[1].ActualHeight}"> 并查看它为子控件分配更多高度时,了解滚动条未显示的原因。