【问题标题】:WPF Items control doesnot show VerticalScrollBar automaticallyWPF Itemscontrol 不自动显示垂直滚动条
【发布时间】:2023-03-30 19:54:01
【问题描述】:

这是意图,

当项目被添加到 ItemsControl 并且内容超过可用大小时,我希望在 ItemsControl 中看到滚动。我敢打赌这是任何 ItemsControl 类型的默认行为。

所以我生成了一个样本来复制我的意图。建议我需要解决的问题

<StackPanel>
        <StackPanel.Resources>
            <Style TargetType="{x:Type ItemsControl}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ItemsControl}">
                            <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                <ScrollViewer VerticalScrollBarVisibility="Visible">
                                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </ScrollViewer>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
        <ToggleButton Name="SomeToggle" Content="Show/Hide"/>
        <Button Content="Add Item" Click="ButtonBase_OnClick" />
        <TextBlock Text="Hide/Show on toggle" >
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Visibility" Value="Collapsed"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsChecked,ElementName=SomeToggle}" Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>

    <ItemsControl Name="ItemsCollection" >
    </ItemsControl>

</StackPanel>

和背后的代码:

private int counter = 0;
    private ObservableCollection<string> coll; 
    public MainWindow()
    {
        coll= new ObservableCollection<string>();
        //ItemsCollection.ItemsSource = coll;
        InitializeComponent();
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        ItemsCollection.Items.Add(string.Format("Item {0}", ++counter));
    }

【问题讨论】:

    标签: wpf wpf-controls itemscontrol


    【解决方案1】:

    这基本上是每次将ScrollViewer 放入Stackpanel 时都会发生的,这是由于Stackpanel 的工作方式,看看here

    您可以将Stackpanel 放在ScrollView 中,或者最好将主面板更改为Grid

       <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>            
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <Style TargetType="{x:Type ItemsControl}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ItemsControl}">
                            <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                <ScrollViewer VerticalScrollBarVisibility="Visible">
                                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </ScrollViewer>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <ToggleButton Name="SomeToggle" Content="Show/Hide" Grid.Row="0"/>
        <Button Content="Add Item" Click="ButtonBase_OnClick" Grid.Row="1"/>
        <TextBlock Text="Hide/Show on toggle" Grid.Row="2">
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Visibility" Value="Collapsed"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsChecked,ElementName=SomeToggle}" Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
        <ItemsControl Name="ItemsCollection" Grid.Row="3">
        </ItemsControl>
    </Grid>
    

    【讨论】:

    • @Sam 如果任何一行网格会变得比网格的容器大(这里说窗口),那么我们可能会遇到一些问题。
    【解决方案2】:

    您看不到滚动条的唯一原因是您没有设置 ItemsControl 的高度。

    每次添加项目时,它的高度都会扩展,而 StackPanel 也会随之扩展以包含内容。您已经为 ItemsControl 模板定义了 ScrollViewer,您还必须决定它必须在什么时候工作。

    <ItemsControl Name="ItemsCollection" Height="200" >
    </ItemsControl>
    

    那么,将它包含在 StackPanel 或任何其他控件中也无关紧要。

    初始滚动条

    添加项目后

    带代码

    仅从理解的角度来看。这也将起作用

    删除项目控件的样式并设置滚动查看器的高度。

    处理所有元素的高度:

    <ScrollViewer MaxHeight="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}},Path=ActualHeight,Mode=OneWay}">
        <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="{x:Type ItemsControl}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ItemsControl}">
                            <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                <ScrollViewer VerticalScrollBarVisibility="Visible">
                                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </ScrollViewer>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
        <ToggleButton Name="SomeToggle" Content="Show/Hide"/>
        <Button Content="Add Item" Click="Button_Click" />
        <TextBlock Text="Hide/Show on toggle" >
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Visibility" Value="Collapsed"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsChecked,ElementName=SomeToggle}" Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    
        <ItemsControl Name="ItemsCollection" ItemsSource="{Binding list}" 
                      MaxHeight="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}},Path=ActualHeight,Mode=OneWay}">
        </ItemsControl>
    
    </StackPanel>
    </ScrollViewer>
    

    【讨论】:

    • 它不会那样工作。只有在它工作时,它才必须被封闭在一个网格中。
    • @user841612 你为什么不这么认为?请通过屏幕截图查看更新的答案。
    • 您发布的场景:当窗口大小很小以仅适合内容并且我动态显示或隐藏项目时,滚动条会在下方移动。因为你有一个固定的高度
    • @user841612 好的。 :) 实际上问题是关于项目的控制滚动条,所以没有为其他人做调整。而且我确定 Grid 也不是您的答案(它在文本框元素很小的情况下工作)。尝试增加文本框的高度(显示/隐藏一个)并查看。如果您真的想实现这一点,那么您必须将滚动查看器放在我的代码中窗口的内容之外。
    • @user841612 一旦文本框的高度增加了网格的高度,您就会看到您的项目控件完全不可见。不仅仅是网格,每个控件都会发生这种情况,这些控件可以包含一些内容但没有滚动查看器来显示整个内容,如网格、Stackpanel、ContentControl 或 Window。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多