WPF Itemscontrol 不会自动显示 Vertical ScrollBar
WPF Items control doesnot show VerticalScrollBar automatically
意图在此,
当项目添加到 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));
}
每次将 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>
您看不到滚动条的唯一原因是您没有设置 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>
意图在此,
当项目添加到 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));
}
每次将 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>
您看不到滚动条的唯一原因是您没有设置 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>