c# - ItemsControl 中的 ScrollViewer - ScrollBar 未显示但有效

标签 c# .net wpf

这不是一般的“我的 ScrollViewer 不工作”问题...
假设有一个带有网格的窗口。第 0 列和第 1 行的大小设置为 Auto,第 1 列和第 0 行的大小设置为 *。 (重要)
在单元格 [0, 0] 中有一个 ItemsControl 和一个模板,在 Grid 中的 ScrollViewer 中有一个 StackPanel >。原因很简单:如果不能显示 ItemsControl 中的所有项目,则显示滚动条。垂直滚动条的可见性设置为 Auto(重要)。
在 Cell [1, 1] 中有一个显示其宽度的 Button

如果窗口太小而无法显示 ItemsControl 中的所有项目,这将导致以下情况: 滚动条将在那里,但不可见。它正在工作,因为我可以使用鼠标滚轮滚动。原因似乎是包含 ItemsControl 的网格列不会自动扩展以为滚动条腾出空间。

如果我更改(几乎)任何 参数,滚动条会按预期显示并且第二列会缩小。 谁能解释这种奇怪的行为?


附加信息:

以下参数更改将导致滚动条可见:

  1. 将第 0 列的大小更改为 *
  2. 将第 1 列的大小更改为自动
  3. 将第 1 行的大小更改为 *
  4. 删除按钮
  5. Button 移动到 [0, 1] 或 [1, 0]
  6. 手动设置 ItemsControl 的宽度。
  7. ItemsControl 中的 ScrollViewerVerticalScrollBarVisibility 设置为 Visible

但是,将 [1, 1] 中的按钮更改为其他内容,例如另一个 ItemsControl 不会改变奇怪的行为,因此它与按钮无关。此外,将 Button 的宽度更改为小于第二列的宽度也不会消除该行为。


完整的复制示例代码:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="343" Width="253">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="*" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <ItemsControl>
      <ItemsControl.Template>
        <ControlTemplate>
          <Grid>
            <Grid.RowDefinitions>
              <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <ScrollViewer VerticalScrollBarVisibility="Auto">
              <StackPanel IsItemsHost="True" />
            </ScrollViewer>
          </Grid>
        </ControlTemplate>
      </ItemsControl.Template>
      <ItemsControl.Items>
        <Button Content="Column1" Height="500" />
      </ItemsControl.Items>
    </ItemsControl>
    <Button Content="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"
            Grid.Column="1" Grid.Row="1" />
  </Grid>
</Window>

最佳答案

看起来这可能是 WPF 中的一个已知错误。 This question处理 ListBox 的 ScrollViewer,但我认为主体是相同的。

作为替代方案,您可以在 ScrollViewer 后面添加一些内容,使其宽度绑定(bind)到 ScrollViewer 的 ActualWidth,这将强制列绘制正确的大小

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <ScrollViewer x:Name="Test" Grid.Row="0" Grid.Column="0" 
                  VerticalScrollBarVisibility="Auto">
        <Button Content="Column1" Height="500" />
    </ScrollViewer>

    <Grid Grid.Column="0" Grid.Row="0" 
          Width="{Binding ElementName=Test, Path=ActualWidth}" />

    <Button Content="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"
        Grid.Column="1" Grid.Row="1" />
</Grid>

关于c# - ItemsControl 中的 ScrollViewer - ScrollBar 未显示但有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7753914/

相关文章:

c# - 为什么 ViewComponent 类没有 Invoke 方法的抽象定义?

c# - RijndaelManaged 返回空结果

c# - 使用 BulkAll 方法嵌套 5.5 重复项

c# - 如何以一种形式发布两个或多个模型?

c# - 如何在WPF中获取应用程序名称

c# - 初始化事件操作以引发事件通知

c# - 我在控制台应用程序中创建了一个类,现在我想创建一个使用该类的 Windows 窗体应用程序

c# - 如何在后台加载图像?

wpf - 需要在后面的代码中创建绑定(bind)并传递参数

c# - 带有可以转售的 API 的 VOIP 服务?