【问题标题】:ScrollBar not visible inside ScrollViewerScrollBar 在 ScrollViewer 中不可见
【发布时间】:2018-12-26 21:40:09
【问题描述】:

我发现自己陷入了这个问题一段时间,我似乎无法解决它。我创建了一个名为TaskListControlUserControl,它本质上是另一个名为TaskListItemControlUserControl 的列表,我希望它在内容溢出但不会发生时显示垂直的ScrollBar

经过一番搜索和测试,我试图分解CustomControl,因为我怀疑问题与项目列表未定义的空间占用有关。我将ScrollViewer 包含在Grid 中,并将其放在MainWindow 中,但没有任何变化。

这是列表中包含的 TaskListItem 的代码:

<UserControl x:Class="CSB.Tasks.TaskListItemControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:CSB.Tasks"
         xmlns:core="clr-namespace:CSB.Tasks.Core;assembly=CSB.Tasks.Core"
         mc:Ignorable="d"
         Height="70"
         d:DesignHeight="100" d:DesignWidth="400">

<!-- Custom control that represents a Task. -->
<UserControl.Resources>
    <!-- The control style. -->
    <Style x:Key="ContentStyle" TargetType="{x:Type ContentControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ContentControl}">

                    <Border x:Name="ContainerBorder" BorderBrush="{StaticResource LightVoidnessBrush}"
                            Background="{StaticResource DeepVoidnessBrush}"
                            BorderThickness="1" 
                            Margin="2">

                        <!-- The grid that contains the control. -->
                        <Grid Name="ContainerGrid" Background="Transparent">

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

                            <!-- Border representing the priority state of the Task:
                            The color is defined by a ValueConverter according to the PriorityLevel of the Task object. -->
                            <Border Grid.Column="0"
                                    Width="10"
                                    Background="{Binding Priority, Converter={local:PriorityLevelToRGBConverter}}">
                            </Border>

                            <!-- Border containing the Task's informations. -->
                            <Border Grid.Column="1" Padding="5">
                                <StackPanel>
                                    <!-- The title of the Task. -->
                                    <TextBlock Text="{Binding Title}" FontSize="{StaticResource TaskListItemTitleFontSize}" Foreground="{StaticResource DirtyWhiteBrush}"/>

                                    <!-- The customer the Taks refers to. -->
                                    <TextBlock Text="{Binding Customer}" Style="{StaticResource TaskListItemControlCustomerTextBlockStyle}"/>

                                    <!-- The description of the Task. -->
                                    <TextBlock Text="{Binding Description}"
                                               TextTrimming="WordEllipsis"
                                               Foreground="{StaticResource DirtyWhiteBrush}"/>
                                </StackPanel>
                            </Border>

                            <!-- Border that contains the controls for the Task management. -->
                            <Border Grid.Column="2"
                                    Padding="5">

                                <!-- Selection checkbox of the Task. -->
                                <CheckBox Grid.Column="2" VerticalAlignment="Center"/>
                            </Border>

                        </Grid>

                    </Border>

                    <!-- Template triggers. -->
                    <ControlTemplate.Triggers>

                        <DataTrigger Binding="{Binding IsSelected}" Value="True">
                            <Setter Property="Background" TargetName="ContainerBorder" Value="{StaticResource VoidnessBrush}"/>
                            <Setter Property="BorderBrush" TargetName="ContainerBorder" Value="{StaticResource PeterriverBrush}"/>
                        </DataTrigger>

                        <EventTrigger RoutedEvent="MouseEnter">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0:0" To="{StaticResource LightVoidness}" Storyboard.TargetName="ContainerGrid" Storyboard.TargetProperty="Background.Color"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>

                        <EventTrigger RoutedEvent="MouseLeave">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0:0" To="Transparent" Storyboard.TargetName="ContainerGrid" Storyboard.TargetProperty="Background.Color"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </ControlTemplate.Triggers>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<!-- Content of the control: assignment of the DataContext for design-time testing. -->
<ContentControl d:DataContext="{x:Static core:TaskListItemDesignModel.Instance}" 
                Style="{StaticResource ContentStyle}"/>

这里是TaskListControl 代码:

<UserControl x:Class="CSB.Tasks.TaskListControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:CSB.Tasks"
         xmlns:core="clr-namespace:CSB.Tasks.Core;assembly=CSB.Tasks.Core"
         mc:Ignorable="d" 
         d:DesignHeight="500" d:DesignWidth="500">

<!-- Custom control that represents a list of TaskListItemControl. -->
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <ScrollViewer Grid.Row="0"
                  VerticalScrollBarVisibility="Auto"
                  HorizontalScrollBarVisibility="Auto"
                  DataContext="{x:Static core:TaskListDesignModel.Instance}"
                  Height="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=Height}">

        <!-- The items shown in the list. -->
        <ItemsControl ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:TaskListItemControl/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

    </ScrollViewer>

</Grid>

如您所见,我设置DataContext 是为了测试控件,我实际上可以在设计预览中看到ScrollBar

编辑:我设法显示了ScrollBar,但它似乎溢出了包含TaskListControlWindow,因为我将它的高度绑定到Window 高度,显然,也考虑到标题栏。 下面是使用控件的MainWindow的代码:

<Window x:Class="CSB.Tasks.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:CSB.Tasks"
    mc:Ignorable="d"
    Title="{StaticResource MainWindow_TitleText}"
    Style="{StaticResource WindowDefaultStyle}"
    Height="500" 
    Width="500"
    WindowStartupLocation="CenterScreen">

<WindowChrome.WindowChrome>
    <WindowChrome ResizeBorderThickness="{Binding ResizeBorderThickness}"
                  GlassFrameThickness="0"
                  CornerRadius="{Binding CornerRadius}"/>
</WindowChrome.WindowChrome>

<local:TaskListControl>
    <local:TaskListControl/>
</local:TaskListControl>

TaskListControl 直接放在Window 中,因为我试图将它放在几乎所有类型的“容器”中(BorderStackPanelGrid 等),但一点运气都没有,高度仍然溢出。

因为我想直接在 UserControl 定义中处理高度,所以每次使用时都避免这样做:

  • 我应该将TaskListControl 放在MainWindow 内的哪个位置(什么类型的容器)?
  • 我应该在UserControl定义中设置TaskListControl的高度(现在绑定到Window高度,但根本不正确)?

这是我到现在为止完成的结果(你可以看到底部的滚动按钮不见了):

有人有什么建议吗? 提前感谢大家的帮助。

【问题讨论】:

  • 所以你的项目在溢出时被剪辑而不显示滚动条?
  • 您是否尝试在 itemscontrol 本身上设置 VerticalScrollBarVisibility 附加属性?我认为该控件带有自己的 ScrollViewer ...另外,避免在 DataTemplate 中使用用户控件会稍微提高性能,只需将 TaskListItemControl 的内容直接放在数据模板中(如果可能的话)
  • @Ehssan 我尝试直接在 itemscontrol 上设置附加属性,但没有任何改变。谢谢你的表演技巧,我试试看。
  • 您是否尝试过不使用高度绑定?然后它应该使用 Grid 的 * 高度并且只填充可用空间。
  • @mami 是的,如果我没有在ScrollViewer 内设置高度,ScrollBar 根本不可见,即使使用了网格的 * 高度。由于问题可能会变得很长,如果您想自己测试它,您可以找到完整的项目drive.google.com/open?id=1eOXEeLEvGAkdOW8RvbTV_pMnKFl4zoQc。感谢您的帮助。

标签: c# wpf xaml custom-controls


【解决方案1】:

对于调试此类问题,最好的方法是将滚动条可见性设置为 Visible,这样您就可以看到 ScrollViewer 是如何增长的。可能它比屏幕尺寸大,如果您将滚动条的可见性设置为可见,底部的滚动按钮将会丢失。

也许你已经把你的用户控件放在一个高度为 * 的容器中,所以它变得比屏幕大,滚动条永远不会显示。

更新:我检查了您的项目,我认为问题出在 Windows.xaml 中的 Grid 上。在第 23-27 行中,像这样更改最后两个 RowDefinition 的顺序:

<Grid.RowDefinitions>
    <RowDefinition Height="{Binding TitleHeight}"/>
    <RowDefinition Height="*"/>
    <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

【讨论】:

  • 我将ScrollBar 可见性设置为可见,它实际上比窗口大小大得多,而不是让我看到你说的底部滚动按钮。现在,我删除了包含ScrollViewerGrid,并手动将Height 设置为500(仅出于测试目的,因为必须动态定义Height)并且ScrollBar“神奇地”出现了。我设法定义了 Height 将其绑定到祖先父级,以便匹配它的父级具有的任何值。感谢您的帮助!
  • 我更新了问题,因为我部分解决了问题,你可以看到编辑。
  • 谢谢,它确实有效。窗口有点小问题,因为它位于任务栏下方,但我会尝试管理它。
猜你喜欢
  • 1970-01-01
  • 2011-09-30
  • 2014-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 2011-09-25
相关资源
最近更新 更多