【问题标题】:Auto Height in combination with MaxHeight自动高度与 MaxHeight 相结合
【发布时间】:2013-07-19 09:23:17
【问题描述】:

我在设置以下 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 控件没有显示任何定义了很多列和行的滚动条。 当我将 Height="Auto" 替换为 Height="*" 时,一切正常,而不是水平和垂直滚动条看起来像预期的那样。

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

这是一个错误,即 childcontrol 在设置 Height="Auto" 时忽略了 maxheight 还是我可能做错了什么?使用 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 表示格式正确并记录在案的第一个问题。欢迎来到 SO :)
  • 请不要写string.Format("Property{0:000}", i) 而不是调用AddLeadingZeros 方法。
  • @Viv:谢谢。 :) @Clemens:感谢您的意见。我是字符串格式的菜鸟。 :)

标签: c# wpf xaml


【解决方案1】:

这和你说的完全一样。

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

要获得您正在寻找的行为,

  • DataGrid 上应用MaxHeight 或使用网格RowDefinition.Height="*"
  • 或者您也可以在DataGrid 上使用RelativeSourceBinding

类似-

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

对于此类问题,Snoop 是您的朋友。当您使用 Snoop 检查 DataGrid 上的 ActualHeight 并看到它为子控件分配了相当多的高度时,您可以轻松检查此行为并了解为什么没有显示滚动条。

【讨论】:

  • 不太明白为什么会发生这种情况,在我的布局中我明确指出我只想要 200 的 MaxHeight。你能解释一下为什么有人在说明时想要一个全尺寸的子元素最大高度?也许是连水平滚动条都没有显示的原因,这对我来说绝对没有意义。
  • @RandRandom 但你也在说Height="Auto",意思是“占据你想要的所有空间”。这只是我的意见。您可以在 MSDN 上将其作为错误提出并询问他们为什么指定 Auto 不会强制子控件尊重 Grid.RowDefinition 上的 MaxHeight。对我来说,如果您将“*”指定为高度,则允许孩子获取“父母的任何可用空间”,这恰好受到 MaxHeight 的限制,因此输出是您所期望的。
  • @RandRandom ..contd。但是,当您设置Height="Auto" 时,会出现不匹配,一方面网格的行被 MaxHeight 强制在 ActualHeight 中仅取 200,而允许孩子通过 Auto for Height 取所需的数量,并且它恰好满足当 Grid 的行本身符合给定的最大 200 时,让孩子占据它需要的空间。
  • @RandRandom 至于水平滚动条,它与这个问题无关,但它是副作用的无辜受害者。水平滚动条的高度超出 200 大小,因此您看不到它。但它总是在DataGrid的底端
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 2014-05-10
  • 1970-01-01
  • 2021-10-02
  • 1970-01-01
相关资源
最近更新 更多