使WrapPanel尊重父母的宽度

时间:2011-06-30 18:10:21

标签: .net wpf user-controls scrollviewer 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>

Code EDITED

请注意,矩形就在那里,因为该滚动查看器的内容无关紧要。

问题是WrapPanel只是水平展开而不会包裹......

我找到了一些解决方案:

  1. 为WrapPanel提供绝对宽度(但随后窗口不会调整大小)。

  2. 将宽度绑定到其父宽度 - ItemsControl或ScrollViewer(ScrollViewer在这种有限的情况下工作得更好)。

    Width="{Binding RelativeSource=
        {RelativeSource FindAncestor,
        AncestorType={x:Type ScrollViewer}},
        Path=ActualWidth}"
    
  3. 这种技术的问题在于,如果一个控件在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易于维护,
    • 我的代码比依赖父控件的Type的大型绑定表达式更清晰。

    什么是更好的解决方案?

    注意:如果有任何不清楚的地方,我可以添加细节。

1 个答案:

答案 0 :(得分:9)

ScrollViewer允许水平滚动时,为什么会换行?您应该在ScrollViewer

中禁用水平滚动
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">

编辑后编辑:这是因为您的StackPanel水平定向。水平导向的StackPanel将提供其子请求的宽度 - 它根本不会限制它。使用右侧面板,你会没事的。可能你只想要一个有两列的Grid