在ScrollViewer中嵌入ItemsControl

时间:2011-07-07 03:26:43

标签: wpf itemscontrol scrollviewer

我已经研究过几个与ScrollViewer相关的问题,但是没有一个问题适合我。这几乎可以肯定是由于我对元素的大小缺乏了解。首先,我的XAML(除了UserControl定义,这是整个控件):

<DockPanel Width="Auto">
            <ScrollViewer DockPanel.Dock="Top" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible" CanContentScroll="True" BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1,1,1,1" Background="{DynamicResource LightGradientBackgroundBrush}">
            <ItemsControl Focusable="false" Width="Auto"  MinHeight="30" ItemsSource="{Binding RequiredFields}" OverridesDefaultStyle="False">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <DockPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="3,0,3,3">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="110"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Label Content="{Binding Path=Header, Mode=OneTime}" Foreground="{DynamicResource SilverBorderColorBrush}" Grid.Column="0"/>
                            <TextBox Text="{Binding Path=Value}" HorizontalAlignment="Stretch" Foreground="{DynamicResource SilverBorderColorBrush}" Grid.Column="1"/>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
        </DockPanel>

此控件作为内容加载到选项卡中。托管选项卡的窗口可以调整大小,选项卡内容的最小大小为60.我要做的是让scrollviewer填充选项卡,但不要将选项卡推过窗口的边界。使用上面的XAML,多余的内容会导致标签高度扩大,并且窗口上出现滚动条,而不是标签。

scrollviewer正在扩展到其子项的大小,因此将标签高度推出。我想要的是,将scrollviewer固定到选项卡的大小,并使scrollviewer中的内容在scrollviewer的范围内增长,以便在内容太多时显示滚动条。

我哪里错了?

编辑:

问题是高度,而不是宽度。宽度表现得如此。我已根据建议将包装器更改为网格,但除非我设置了Height属性,否则网格会扩展以适应展开的scrollviewer的内容,从而导致与以前相同的问题。

更新了XAML:

<Grid MinHeight="60" VerticalAlignment="Top">
        <Border BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1,1,1,1">
        <ScrollViewer 
            HorizontalScrollBarVisibility="Auto" 
            VerticalScrollBarVisibility="Visible" 
            CanContentScroll="True" 
            BorderBrush="{DynamicResource PanelBorder}" 
            BorderThickness="1,1,1,1" 
            Background="{DynamicResource LightGradientBackgroundBrush}"
            >
            <ItemsControl Focusable="false" Width="Auto"  MinHeight="30" ItemsSource="{Binding RequiredFields}" OverridesDefaultStyle="False">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="3,0,3,3">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="110"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Label Content="{Binding Path=Header, Mode=OneTime}" Foreground="{DynamicResource SilverBorderColorBrush}" Grid.Column="0"/>
                            <TextBox Text="{Binding Path=Value}" HorizontalAlignment="Stretch" Foreground="{DynamicResource SilverBorderColorBrush}" Grid.Column="1"/>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemContainerStyle>
                    <Style>
                        <Setter Property="DockPanel.Dock" Value="Top"/>
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
        </ScrollViewer>
        </Border>
    </Grid>

以下答案都没有帮助实现这一目标,但我相信大多数情况下答案都有效。

我的控件托管在标签页中。它是动态加载的,我无法控制标签页的设计方式。我的直觉是,标签控件允许与其中的内容一样多的空间。因为我控制中的网格用尽了所有可用空间,并且标签页提供了与子容器所需的空间一样多的空间,而itemscontrol正在尝试使用网格提供的空间;它最终在标签页面展开以包含整个ItemsControl内容。

如果创建的标签页未展开以适合其内容,则以下解决方案可行。不幸的是,我不相信这种情况。

整整一天浪费在这上面。是时候继续前进了。

2 个答案:

答案 0 :(得分:6)

啊是的,WPF布局的复杂性有时会很痛苦。杀死你的是你的ItemsControl上的DockPanel和Width =“Auto”的组合。 DockPanel告诉它的孩子他们可以拥有他们想要的布局空间。然后你的ItemsControl告诉它的孩子同样的事情。最后,Window创建了一个ScrollViewer来处理超大内容。

用网格替换外部DockPanel,一切都很好。

答案 1 :(得分:1)

要让scrollviewer不强,您需要使用Grid容器

<Grid>            
<ScrollViewer DockPanel.Dock="Top" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible" CanContentScroll="True" BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1,1,1,1" Background="{DynamicResource LightGradientBackgroundBrush}">  
...
</ScrollViewer>        
</Grid>

DockPanel和StackPanel总是拉伸以适合它的孩子

另请参阅此说明(我已复制自here

面板X尺寸Y尺寸

画布否否

码头是是

的StackPanel (垂直)是否

的StackPanel (水平)否是

网格是*是*

WrapPanel否否

  • 使用“自动”行和列
  • 除外

上表中的是表示“儿童被拉伸到可用尺寸”

上表中没有表示“孩子是他们想要的大小”