Автоматическая высота в сочетании с MaxHeight
У меня возникла проблема с настройкой следующего макета 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 = "*", чем горизонтальные и вертикальные полосы прокрутки, как ожидалось.
Также он работает, когда я объявляю MaxHeight непосредственно в DataGrid1, но этого действительно не хочу.
Является ли это ошибкой, что childcontrol игнорирует maxheight при установке Height = "Auto" или я могу сделать что-то неправильно? То же поведение можно воспроизвести с помощью ListBox/ListView и т.д., А также с сторонними элементами управления, такими как ComponentOne, Telerik...
Если это ошибка - знаете ли вы обходной путь или имеете другие подсказки для меня?
Вот код, как я устанавливаю ItemsSource 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; }
}
Ответы
Ответ 1
Это точно так, как вы говорите.
Причина, по которой вы не видите Scrollbar
, состоит в том, что даже если Grid
Clip the DataGrid
, это просто клип, ActualHeight
DataGrid
- это высота, которую он получит, если разрешено чтобы показать все это детям. Таким образом, вы не видите его полосу прокрутки. ActualHeight
, так что это позволило получить все необходимое пространство с Height="Auto"
на Grid
. Причина, по которой я бы не назвал это ошибкой лично, потому что вы можете захотеть этого поведения, если хотите сыграть с свойством ClipToBounds
для Grid
для определенных анимаций, и это поведение, которое вы желаете. Думаю об этом, я на самом деле думаю, что я бы назвал это ошибкой тоже с точки зрения "Нежелательной функциональности", чем "Неправильный вывод"
Чтобы получить поведение, которое вы ищете,
- Примените
MaxHeight
к DataGrid
или используйте Grid RowDefinition.Height="*"
< - оба, как вы упомянули (не знаете, почему вы говорите, что это не то, что вы хотите сделать?)
- Или вы также можете использовать
RelativeSourceBinding
на DataGrid
что-то вроде -
<DataGrid Name="DataGrid1"
Grid.Row="1"
Height="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Grid}},
Path=RowDefinitions[1].ActualHeight}">
Для таких проблем Snoop - ваш друг. Вы можете легко проверить это поведение и понять, почему полоса прокрутки не отображается, когда вы проверяете ActualHeight
на вашем DataGrid
с помощью Snoop и видите, что дочерний элемент выделяет достаточно большую высоту.