【发布时间】:2018-12-26 21:40:09
【问题描述】:
我发现自己陷入了这个问题一段时间,我似乎无法解决它。我创建了一个名为TaskListControl 的UserControl,它本质上是另一个名为TaskListItemControl 的UserControl 的列表,我希望它在内容溢出但不会发生时显示垂直的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,但它似乎溢出了包含TaskListControl 的Window,因为我将它的高度绑定到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 中,因为我试图将它放在几乎所有类型的“容器”中(Border、StackPanel、Grid 等),但一点运气都没有,高度仍然溢出。
因为我想直接在 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