C# 自动高度与 MaxHeight 结合使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17742513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 10:23:20  来源:igfitidea点击:

Auto Height in combination with MaxHeight

c#wpfxaml

提问by Rand Random

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

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

RowHeightAuto.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>

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.

DataGrid1 控件未显示任何已定义大量列和行的滚动条。一切正常,当我将 Height="Auto" 替换为 Height="*" 时,水平和垂直滚动条看起来像预期的那样。

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

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

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...

这是 childcontrol 在设置 Height="Auto" 时忽略 maxheight 的错误还是我可能做错了什么?可以使用 ListBox/ListView 等重现相同的行为,也可以使用 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

这是我如何设置 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; }

}

采纳答案by Viv

This is exactly as you say it is.

这正是你所说的。

The reason why you do not see the Scrollbar's is because even though the GridClip's the DataGrid, it's merely a Clip, the ActualHeightof the DataGridis the height it would get if allowed to show all it's children. You are thus not seeing it's scrollbar's. ActualHeightis 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 ClipToBoundsproperty of the Gridfor 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"

为什么你没有看到的原因Scrollbar的是因为即使Grid剪辑的DataGrid,它只是一个片段,该ActualHeightDataGrid是高度,如果允许显示所有它的孩子会得到。因此,您看不到它的滚动条。ActualHeight是因为它允许Height="Auto"Grid. 我个人不会将此称为错误的原因是因为如果您想使用某些动画的ClipToBounds属性,您可能希望这种行为,Grid而这正是您希望的行为。考虑到这一点,我实际上认为我也将其称为“不理想的功能”而不是“错误的输出”

To get the behavior your looking for,

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

  • Apply the MaxHeighton the DataGridor 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 RelativeSourceBindingon the DataGrid
  • 应用MaxHeightDataGrid或使用网RowDefinition.Height="*"< -无论你所说的(?不知道为什么你说这是不是你想要做什么)
  • 或者你也可以RelativeSourceBindingDataGrid

something like -

就像是 -

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

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

对于此类问题,Snoop是您的朋友。您可以轻松地检查这种行为,并意识到你为什么不显示滚动条的时候,你检查ActualHeight你的DataGrid使用snoop,看它分配相当多的高度与子控件。