自动高度与 MaxHeight 结合使用 [英] Auto Height in combination with MaxHeight
问题描述
我在设置以下 xaml 布局时遇到问题:
I am facing a problem with setting the following xaml layout:
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>
DataGrid1 控件没有显示任何定义了大量列和行的滚动条.一切正常,当我将 Height="Auto" 替换为 Height="*" 时,水平和垂直滚动条看起来像预期的那样.
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 上声明 MaxHeight 时它也可以工作,但这并不是我真正想要的.
Also it works when I would declare the MaxHeight directly at the DataGrid1, but that's not really want I want.
这是 childcontrol 在设置 Height="Auto" 时忽略 maxheight 的错误还是我可能做错了什么?同样的行为可以用 ListBox/ListView 等重现,也可以用第三方控件如 ComponentOne、Telerik...
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?
这是我如何设置 DataGrid 的 ItemsSource 的代码.RowHeightAuto.xaml.cs
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; }
}
推荐答案
正如你所说的那样.
你没有看到 Scrollbar
的原因是因为即使 Grid
Clip 是 DataGrid
,它只是一个 Clip,DataGrid
的 ActualHeight
是如果允许显示所有子项的高度.因此,您看不到它的滚动条.ActualHeight
是如此,因为它允许使用 Height="Auto"
在 Grid
上获得它想要的所有空间.我个人不会将其称为错误的原因是因为如果您想使用 考虑到这一点,我实际上认为我也将其称为不理想的功能"而不是错误的输出"Grid
的 ClipToBounds
属性来播放某些动画,您可能希望这种行为这就是您想要的行为.
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 Thinking about this, I actually think I'd call this a bug too in terms of "Not desirable functionality" than "Incorrect output"ClipToBounds
property of the Grid
for certain animations and this is the behavior you desire.
要获得您想要的行为,
- 在
DataGrid
上应用MaxHeight
或使用 GridRowDefinition.Height="*"
<- 正如你提到的(不确定为什么你说这不是你想做的?) - 或者您也可以在
DataGrid
上使用
RelativeSourceBinding
- Apply the
MaxHeight
on theDataGrid
or use GridRowDefinition.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 theDataGrid
类似 -
<DataGrid Name="DataGrid1"
Grid.Row="1"
Height="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Grid}},
Path=RowDefinitions[1].ActualHeight}">
对于此类问题,Snoop 是您的朋友.您可以轻松检查此行为并了解为什么在使用 Snoop 检查 DataGrid
上的 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.
这篇关于自动高度与 MaxHeight 结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!