Панель WPF wrap и прокрутка
У меня есть простой WrapPanel, который содержит ряд широких элементов управления. Когда я изменяю размер Width из Window, все работает, как и ожидалось. Элементы управления будут проходить по одной строке, если есть достаточно места, или сворачиваться к следующей строке, когда его нет.
Однако, что мне нужно сделать, так это то, что если все элементы управления в основном сложены вертикально (так как горизонтального пространства больше нет) и Width из Window уменьшается еще больше, горизонтальная полоса прокрутки появляется так что я могу прокрутить и увидеть весь контроль, если захочу. Ниже приведен мой xaml. Я попытался обернуть WrapPanel в ScrollViewer, но не смог достичь своей цели.
<Window x:Class="WpfQuotes.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="Auto" Width="600" Foreground="White">
<WrapPanel>
<Button Width="250">1</Button>
<Button Width="250">2</Button>
<Button Width="250">3</Button>
</WrapPanel>
</Window>
Таким образом, если вы уменьшите
Width из приведенных выше Window до минимума, вы не сможете увидеть текст кнопок. Я хотел бы, чтобы появилась горизонтальная полоса прокрутки, чтобы я мог прокручивать текст, но не мешал обычной функции переноса.Спасибо.
Обновление:
Я последовал примеру Павла. предложение ниже, и горизонтальная полоса прокрутки появляется, как и ожидалось. Однако я также хотел, чтобы вертикальная прокрутка была доступна, поэтому я установил VerticalScrollBarVisibility="Auto". Дело в том, что если я изменяю размер окна так, что появляется вертикальная полоса прокрутки, горизонтальная также всегда появляется, даже если она не нужна (есть достаточно горизонтального пространства, чтобы увидеть весь элемент управления). Похоже, что вертикальная полоса прокрутки, появляющаяся, путается с шириной scrollviewer. Есть ли способ исправить это так, чтобы горизонтальная полоса прокрутки не появляется, если это действительно необходимо?
Ниже приведен мой xaml и единственный код, который я добавил в CustomWrapPanel:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwp="clr-namespace:CustomWrapPanelExample"
Title="Window1" Height="Auto" Width="300" Foreground="White" Name="mainPanel">
<ScrollViewer x:Name="MyScrollViewer" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<cwp:CustomWrapPanel Width="{Binding ElementName=MyScrollViewer, Path=ActualWidth}">
<Button Width="250">1</Button>
<Button Width="250">2</Button>
<Button Width="250">3</Button>
<Button Width="250">4</Button>
<Button Width="250">5</Button>
<Button Width="250">6</Button>
<Button Width="250">7</Button>
<Button Width="250">8</Button>
<Button Width="250">9</Button>
</cwp:CustomWrapPanel>
</ScrollViewer>
</Window>
Единственное, что переопределено в CustomWrapPanel:
protected override Size MeasureOverride(Size availableSize)
{
double maxChildWidth = 0;
if (Children.Count > 0)
{
foreach (UIElement el in Children)
{
if (el.DesiredSize.Width > maxChildWidth)
{
maxChildWidth = el.DesiredSize.Width;
}
}
}
MinWidth = maxChildWidth;
return base.MeasureOverride(availableSize);
}
1 ответ:
Вот в чем дело, если вы собираетесь использовать оберточную панель, она делает две вещи, она будет занимать столько свободного пространства в одном направлении и расширяться по мере необходимости в другом. Например, если вы поместите его внутри окна, как у вас есть, он занимает столько горизонтального пространства, сколько может, а затем расширяется по мере необходимости вниз, поэтому вертикальная полоса прокрутки будет работать, родительский контейнер говорит: "это то, насколько я широк, но вы можете сделать себя таким большим, как хотите по вертикали", если вы измените его на вертикальную полосу прокрутки. горизонтальная полоса прокрутки, средство просмотра прокрутки по существу говорит: "это то, насколько вы можете быть высокими, но вы можете быть настолько широкими, насколько вы хотите" в этом случае панель обертывания не обертывается, потому что нет горизонтальных ограничений.
Одно из возможных решений состоит в том, чтобы изменить направление обертывания панели с горизонтального на вертикальное, как это (что, вероятно, не является идеальным или ожидаемым поведением):<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"> <WrapPanel Orientation="Vertical"> <Button Width="250">1</Button> <Button Width="250">2</Button> <Button Width="250">3</Button> </WrapPanel> </ScrollViewer>Чтобы получить поведение, которого вы ожидаете, вам придется сделать что-то более близкое к это:
<ScrollViewer x:Name="MyScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"> <WrapPanel MinWidth="250" Width="{Binding ElementName=MyScrollViewer, Path=ViewportWidth}"> <Button Width="250">1</Button> <Button Width="250">2</Button> <Button Width="250">3</Button> </WrapPanel> </ScrollViewer>Однако это второе решение работает только в том случае, если вы уже знаете ширину ваших дочерних элементов, в идеале вы хотите, чтобы ваша максимальная ширина была установлена на фактическую ширину самого большого дочернего элемента, но для этого вам придется создать пользовательский элемент управления, производный от wrap panel, и написать код самостоятельно, чтобы проверить это.
Comments