Заставить WrapPanel уважать ширину своего родителя - PullRequest
7 голосов
/ 30 июня 2011

Хорошо, вот мой код.Обратите внимание, что StackPanel находится непосредственно в UserControl.

<UserControl>
    <StackPanel Orientation="Horizontal">

        <ScrollViewer Width="450"
                      VerticalScrollBarVisibility="Auto"
                      HorizontalScrollBarVisibility="Disabled">

            <Rectangle Width="400" Height="4000" Fill="BlanchedAlmond"/>
        </ScrollViewer>

        <ScrollViewer VerticalScrollBarVisibility="Auto"
                      HorizontalScrollBarVisibility="Disabled">

            <ItemsControl BorderBrush="Green"
                          BorderThickness="2"
                          ItemsSource="{Binding Path=MyObservableCollection}"
                          ItemTemplate="{StaticResource FatTemplate}">

                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

            </ItemsControl>
        </ScrollViewer>

    </StackPanel>
</UserControl>

( Код EDITED )

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

Проблема в том, что WrapPanel просто расширяется по горизонтали и не переносится ...

Я нашел несколько решений:

  1. Дачаабсолютная ширина для WrapPanel (но затем она не изменяется с размером окна).

  2. Привязка ширины к родительской ширине - ItemsControl или ScrollViewer (ScrollViewer работал лучше в ограниченной ситуации, напримерэтот).

    Width="{Binding RelativeSource=
        {RelativeSource FindAncestor,
        AncestorType={x:Type ScrollViewer}},
        Path=ActualWidth}"
    

Проблема с этой техникой состоит в том, что если элемент управления находится рядом с ним в StackPanel или Grid, вам необходимо привязать его к родительскому размеру минус элемент управлениярядом с ним.Затем идут тяжелые вещи.Я построил конвертер, который применяет математические операции к полученному числу, чтобы я мог вычесть данную ширину из ее родительской ширины:

Width="{Binding RelativeSource=
    {RelativeSource FindAncestor,
    AncestorType={x:Type UserControl}},
    Path=ActualWidth,
    Converter={StaticResource Convertisseur_Size_WXYZ}, 
    ConverterParameter=-260}"

Но, тем не менее, поскольку вы не можете связать значение, передаваемое в ConverterParameter,

ConverterParameter={Binding ...} (doesn't work)

Я хочу:

  • , чтобы иметь возможность изменять размеры моего приложения с помощью WrapPanel и ScrollViewer, изменяя размер,
  • мой UserControl, чтобы его было легко поддерживать,1036 *
  • мой код чище, чем эти большие выражения связывания, которые основаны на типе родительского элемента управления.

Какое лучшее решение?

Примечание: Если что-нибудьне ясно, я могу добавить детали.

1 Ответ

9 голосов
/ 30 июня 2011

Зачем это оборачивать, когда ScrollViewer позволяет горизонтальную прокрутку? Вы должны отключить горизонтальную прокрутку в ScrollViewer:

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">

РЕДАКТИРОВАТЬ ПОСЛЕ ВАШЕГО РЕДАКТИРОВАНИЯ: Это потому, что ваш StackPanel ориентирован горизонтально. Горизонтально-ориентированный StackPanel даст любую ширину, которую запрашивает его дочерний элемент - он вообще не будет ограничивать это. Используйте правую панель, и все будет в порядке. Скорее всего, вы просто хотите Grid с двумя столбцами.

...