Настройка элемента управления WPF на расширение для заполнения доступного пространства, и не более
-
19-09-2019 - |
Вопрос
Как я могу настроить элемент управления WPF так, чтобы он заполнял доступное пространство в его родительском контейнере, но не расширял родительский?
Следующий фрагмент описывает макет, который я пытаюсь создать.Я бы хотел, чтобы Grid
растягиваться, чтобы вместить Expander
, и я хотел бы , чтобы ListBox
только для того, чтобы заполнить Grid
.Я хочу, чтобы ListBox
полоса прокрутки, которая появится, когда Grid
слишком мал, чтобы показать все ListBoxItem
s.
<ScrollViewer>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Grid.Column="0" />
<Expander Grid.Row="0" Grid.Column="1" Header="Expander" />
</Grid>
</ScrollViewer>
В настоящее время происходит то, что Grid
растягивается, чтобы соответствовать всему ListBox
, и внешний ScrollViewer
появится вертикальная полоса прокрутки.Я хочу, чтобы внешняя полоса прокрутки появлялась только тогда, когда Expander
становится слишком большим, чтобы поместиться на экране.
Решение
Чтобы решить ту же проблему, я написал специальный класс контейнера:
class FrugalContainer : Decorator
{
protected override Size MeasureOverride(Size availableSize)
{
return new Size(0, 0);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
// get it all
Child.Measure(arrangeSize);
Child.Arrange(new Rect(arrangeSize));
return Child.RenderSize;
}
}
Окружите свой ListBox контейнером, и высота ListBox будет такой же, как у Expander.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<FrugalContainer Grid.Row="0" Grid.Column="0" >
<ListBox />
</FrugalContainer>
<Expander Grid.Row="0" Grid.Column="1" Header="Expander" />
</Grid>
Обратите внимание, что я удаляю Width="Auto"
из определения столбца, потому что FrugalContainer будет настолько маленьким, насколько это возможно.Таким образом, вы не можете установить ширину или высоту ячейки родительской сетки в значение Auto.
Если вам нужен автоматический размер, перепишите контейнер заново:
class FrugalHeightContainer : Decorator
{
protected override Size MeasureOverride(Size availableSize)
{
Child.Measure(availableSize);
return new Size(Child.DesiredSize.Width, 0);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
Child.Measure(arrangeSize);
Child.Arrange(new Rect(arrangeSize));
return Child.RenderSize;
}
}
Другие советы
В чем смысл этого ScrollViewer
?Просто позвольте ScrollViewer
в ListBox
шаблон появляется естественным образом, когда доступно слишком мало места.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Grid.Column="0" />
<Expander Grid.Row="0" Grid.Column="1" Header="Expander" />
</Grid>