开发者

Making a WrapPanel respect his parent's width

开发者 https://www.devze.com 2023-03-17 00:19 出处:网络
Ok here\'s my code. Note that the StackPanel is directly in a UserControl. <UserControl> <StackPanel Orientation=\"Horizontal\">

Ok here's my code. Note that the StackPanel is directly in a 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="H开发者_运维百科orizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

            </ItemsControl>
        </ScrollViewer>

    </StackPanel>
</UserControl>

(Code EDITED)

Note that the rectangle is just there because the content of that scroll viewer is irrelevant.

The problem is that the WrapPanel just expands horizontally and doesn't wrap...

I found a few solutions:

  1. Giving absolute width to the WrapPanel (but then it doesn't resize with the window).

  2. Binding width to its parent width - either ItemsControl or ScrollViewer (ScrollViewer worked better in a limited situation like this one).

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

The problem with this technique is that if a control is beside it in a StackPanel or Grid, you need to bind it to it's parent size minus the control next to it. Then comes the hard stuff. I built a converter which applies mathematical operations on the number received so I could subtract a given width from its parent width:

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

But still, since you can't bind a value you pass to a ConverterParameter,

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

I want:

  • to be able to resize my app with my WrapPanel and ScrollViewer resizing well,
  • my UserControl to be easily maintainable,
  • my code cleaner than these big binding expressions which rely on parent control's Type.

What's a better solution?

Note: If anything isn't clear, I can add detail.


Why would it wrap when the ScrollViewer allows horizontal scrolling? You should disable horizontal scrolling in the ScrollViewer:

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

EDIT AFTER YOUR EDIT: It's because your StackPanel is oriented horizontally. A horizontally-oriented StackPanel will give whatever width its child requests to it - it won't constrain it at all. Use the right panel, and you'll be fine. Likely you just want a Grid with two columns.

0

精彩评论

暂无评论...
验证码 换一张
取 消