Подтвердить что ты не робот

Панель WPF и прокрутка

У меня есть простой 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 до минимума, вы не сможете увидеть текст кнопок. Я бы хотел, чтобы горизонтальная полоса прокрутки появлялась так, чтобы я мог прокручивать, чтобы увидеть текст, но не вмешиваться в обычные функции обертывания.

Спасибо.

Update: Я последовал за предложением Павла ниже, и горизонтальная полоса прокрутки теперь выглядит так, как ожидалось. Однако я также хотел, чтобы была доступна вертикальная прокрутка, поэтому я установил 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);
}
4b9b3361

Ответ 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>

Однако это второе решение работает только в том случае, если вы уже знаете ширину дочерних элементов, в идеале вы хотите, чтобы ваша максимальная ширина была установлена ​​на фактическую ширину самого большого дочернего элемента, но для этого вы бы для создания настраиваемого элемента управления, который выводится из панели обложки и записывает код самостоятельно, чтобы проверить это.