我目前正在尝试在WPF中实现自己的程式化ComboBox。除滚动查看器外,一切正常。简单地说,垂直滚动条什么都不做。这是一张图片:
正如您所看到的,垂直滚动条一直向下滚动,但它似乎没有触发实际滚动的效果。我在Combobox中有12个虚拟物品。我在网上读到ScrollViewer样式需要三件事:ScrollContentPresenter,VerticalScrollBar和HorizontalScrollBar。我在滚动查看器样式中声明了所有三个,如下所示:
<Style x:Key="VoidwalkerDarkScrollviewer" TargetType="{x:Type ScrollViewer}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="Padding" Value="4" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFA3AEB9" />
<GradientStop Offset="0.375" Color="#FF8399A9" />
<GradientStop Offset="0.375" Color="#FF718597" />
<GradientStop Offset="1" Color="#FF617584" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ScrollContentPresenter
x:Name="ScrollContentPresenter"
Margin="{TemplateBinding Padding}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}" />
<Rectangle
Grid.Row="1"
Grid.Column="1"
Fill="#FFE9EEF4" />
<ScrollBar
x:Name="VerticalScrollBar"
Grid.Row="0"
Grid.Column="1"
Width="18"
Margin="0,-1,-1,-1"
Background="Red"
IsTabStop="False"
Maximum="{TemplateBinding ScrollableHeight}"
Minimum="0"
Orientation="Vertical"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{TemplateBinding VerticalOffset}" />
<ScrollBar
x:Name="HorizontalScrollBar"
Grid.Row="1"
Grid.Column="0"
Height="18"
Margin="-1,0,-1,-1"
IsTabStop="False"
Maximum="{TemplateBinding ScrollableWidth}"
Minimum="0"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{TemplateBinding HorizontalOffset}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是我的Combobox风格(省略不相关的额外内容)
<Style x:Key="VoidwalkerDarkComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Grid.Column="2"
ClickMode="Press"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource ComboBoxToggleButton}" />
<ContentPresenter
Name="ContentSite"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="False" />
<TextBox
x:Name="PART_EditableTextBox"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="Transparent"
Focusable="True"
Foreground="#d0d0d0"
IsReadOnly="{TemplateBinding IsReadOnly}"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
Text="{TemplateBinding Text}"
Visibility="Visible" />
<Popup
Name="Popup"
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid
Name="DropDown"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
SnapsToDevicePixels="True">
<Border
x:Name="DropDownBorder"
Background="#1b1b1c"
BorderBrush="#3f3f46"
BorderThickness="1" />
<ScrollViewer
Margin="4,6,4,6"
SnapsToDevicePixels="True"
Style="{DynamicResource VoidwalkerDarkScrollviewer}"><!-- IF I REMOVE THIS STYLE EVERYTHING WORKS FINE !-->
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="LightGray" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,4,4" />
<Setter TargetName="DropDownBorder" Property="Margin" Value="0" />
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false" />
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
正如样式中的评论所暗示的那样,如果我只是从组合框中删除ScrollViewer样式,一切正常......但我需要它来完成我的黑暗主题。
有没有人知道我缺少什么来使这项工作?
答案 0 :(得分:1)
重写ScrollViewer模板以更改ScrollBar颜色是一种过度杀伤。
ScrollBar是ScrollViewer的一部分,它是ComboBox的一部分。在ComboBox样式的Resources中添加默认的ScrollBar样式,并通过setter更改颜色:
<Style TargetType="ComboBox">
<Style.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="Red"/>
</Style>
</Style.Resources>
</Style>
答案 1 :(得分:0)
我明白了。只需要在网上深入挖掘一下。这里有一些工作的XAML(有些可能不需要,但它是完整的组合框造型)和一张图片来展示它)
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border
x:Name="Border"
Grid.ColumnSpan="2"
Background="#3f3f46"
BorderBrush="#3f3f46"
BorderThickness="1" />
<Border
Grid.Column="0"
Margin="1"
Background="#333337"
BorderBrush="#3f3f46"
BorderThickness="0,0,1,0" />
<Path
x:Name="Arrow"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="#d0d0d0" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="LightGray" />
<Setter TargetName="Border" Property="BorderBrush" Value="Gray" />
<Setter Property="Foreground" Value="DarkGray" />
<Setter TargetName="Arrow" Property="Fill" Value="DarkGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<ScrollViewer
x:Name="PART_ContentHost"
Background="{TemplateBinding Background}"
Focusable="False" />
</ControlTemplate>
<ControlTemplate x:Key="ScrollBackground" TargetType="RepeatButton">
<Border Background="Transparent" />
</ControlTemplate>
<Style x:Key="ScrollThumbStyle" TargetType="Thumb">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Rectangle
Width="13"
Fill="#7D7D7D"
RadiusX="5"
RadiusY="5" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ComboBox style -->
<Style x:Key="VoidwalkerDarkComboBox" TargetType="{x:Type ComboBox}">
<Style.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Width="15">
<Border
Width="13"
HorizontalAlignment="Center"
Background="#33555555"
CornerRadius="5" />
<Track
Name="PART_Track"
Width="{TemplateBinding Width}"
HorizontalAlignment="Center"
IsDirectionReversed="true"
Maximum="{TemplateBinding Maximum}"
Minimum="{TemplateBinding Minimum}"
Value="{TemplateBinding Value}">
<Track.DecreaseRepeatButton>
<RepeatButton Command="ScrollBar.LineUpCommand" Template="{StaticResource ScrollBackground}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="ScrollBar.LineDownCommand" Template="{StaticResource ScrollBackground}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollThumbStyle}" />
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Grid.Column="2"
ClickMode="Press"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource ComboBoxToggleButton}" />
<ContentPresenter
Name="ContentSite"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="False" />
<TextBox
x:Name="PART_EditableTextBox"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="Transparent"
Focusable="True"
Foreground="#d0d0d0"
IsReadOnly="{TemplateBinding IsReadOnly}"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
Text="{TemplateBinding Text}"
Visibility="Visible" />
<Popup
Name="Popup"
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid
Name="DropDown"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
SnapsToDevicePixels="True">
<Border
x:Name="DropDownBorder"
Background="#1b1b1c"
BorderBrush="#3f3f46"
BorderThickness="1" />
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="LightGray" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,4,4" />
<Setter TargetName="DropDownBorder" Property="Margin" Value="0" />
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false" />
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我最好的猜测是,最初重写ScrollViewer本身必须在内部打破一些东西......也许我遗漏了一些东西。我不知道。无论哪种方式,解决方案/替代方案只是为滚动条本身提供样式,并完全忽略ScrollViewer。