Создание WrapPanel с учетом ширины его родителя

Хорошо, вот мой код. Обратите внимание, что 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>

(Код ИЗМЕНЕНО)

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

Проблема в том, что 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 должен быть легко обслуживаемым,
  • мой код чище, чем эти большие выражения привязки, которые полагаются на тип родительского элемента управления.

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

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


person Gab    schedule 30.06.2011    source источник
comment
Он отлично работает в сетке вместо StackPanel, может, это небольшая ошибка изменения размера с StackPanel или что-то в этом роде?   -  person Gab    schedule 30.06.2011
comment
Я не думаю, что это ошибка. Если вы поместите элемент управления в ячейку сетки, его размер по умолчанию будет соответствовать размеру доступного пространства в этой ячейке. StackPanel этого не сделает. Есть ли причина, по которой вы не можете использовать сетку с двумя ячейками вместо StackPanel?   -  person haagel    schedule 30.06.2011
comment
Я мог бы просто использовать сетку. Сначала StackPanel казался лучше, потому что он немного чище для глаз, когда вы смотрите на код, но, как сказал Кент, это вызывает проблемы.   -  person Gab    schedule 01.07.2011


Ответы (1)


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

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

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

person Kent Boogaart    schedule 30.06.2011
comment
Я не заметил, ты! В моем простом случае это сработало очень хорошо, но затем я попробовал это в своем реальном приложении, и это не сработало. Я дополню свой вопрос дополнительным кодом, чтобы вы могли понять, что не так. У меня есть 2 средства просмотра прокрутки в одной StackPanel. - person Gab; 30.06.2011