WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。 本文主要内容:
二.ScrollViewer自定义样式 ScrollViewer在各种列表、集合控件中广泛使用的基础组建,先看看效果图: 如上图,ScrollViewer简单来说分两部分,一个横向的滚动条,一个垂直滚动条,两个样式、模板、功能都基本一样,他们都是ScrollBar。以垂直滚动条为例,分解一下,分解图:
上面实现的是一个标准的垂直滑动条ScrollBar组成,实际可用根据需求定制,实现不同效果的滑动效果。以上各部分的样式代码: ![]() 最后ScrollViewer的样式如下,其实就是两个 ScrollBar组成: <!--ScrollViewer样式--> <Style x:Key="DefaultScrollViewer" TargetType="{x:Type ScrollViewer}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollViewer}"> <Grid x:Name="Grid" Background="{TemplateBinding Background}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" x:Name="leftColumn" /> <ColumnDefinition Width="Auto" x:Name="rightColumn" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" Grid.Row="0" Grid.Column="0" /> <!--垂直滚动条 --> <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" ViewportSize="{TemplateBinding ViewportHeight}" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/> <!--水平底部滚动条--> <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> 使用很简单,如果想通用,把上面定义的ScrollViewer设置为默认样式即可: <Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource DefaultScrollBar}"></Style> <Style TargetType="{x:Type ScrollViewer}" BasedOn="{StaticResource DefaultScrollViewer}"></Style> 三.ListBox样式定义 ListBox是最基础、常用的集合控件,效果: ListBox的样式比较简单,包括两部分:
完整代码: <Style x:Key="DefaultListBoxItem" TargetType="{x:Type ListBoxItem}"> <Setter Property="Foreground" Value="{StaticResource TextForeground}" /> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <!--<Setter Property="VerticalContentAlignment" Value="Center" />--> <Setter Property="MinHeight" Value="25" /> <Setter Property="Margin" Value="0" /> <Setter Property="Background" Value="Transparent" /> <Setter Property="Padding" Value="3,0,0,0" /> <Setter Property="SnapsToDevicePixels" Value="True" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <Border x:Name="Border" Background="{TemplateBinding Background}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"> <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="Border" Property="Background" Value="{StaticResource ItemSelectedBackground}" /> <Setter Property="Foreground" Value="{StaticResource ItemSelectedForeground}" /> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="Border" Property="Background" Value="{StaticResource ItemMouseOverBackground}" /> <Setter Property="Foreground" Value="{StaticResource ItemMouseOverForeground}" /> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="Border" Property="Opacity" Value="{StaticResource DisableOpacity}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="DefaultListBox" TargetType="{x:Type ListBox}"> <Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" /> <Setter Property="Background" Value="{StaticResource ItemsContentBackground}" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="ItemContainerStyle" Value="{StaticResource DefaultListBoxItem}"></Setter> <Setter Property="SnapsToDevicePixels" Value="True" /> <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="False"></Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBox}"> <Border Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ScrollViewer> <ItemsPresenter /> </ScrollViewer> </Border> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="Border" Property="Opacity" Value="{StaticResource DisableOpacity}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> ListBox默认是支持虚拟化的,当加载大数据时需要开启虚拟化,或者定义一个虚拟化的样式: <!--支持虚拟化的ListBox--> <Style x:Key="VirtualListBox" TargetType="{x:Type ListBox}" BasedOn="{StaticResource DefaultListBox}"> <Setter Property="ScrollViewer.CanContentScroll" Value="True" /> <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"></Setter> <Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling" /> <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" /> </Style> 上面演示效果的代码示例: <ListBox Margin="5" SelectionMode="Multiple" > <ListBoxItem Style="{StaticResource RadioButtonListBoxItem}">男</ListBoxItem> <ListBoxItem Style="{StaticResource RadioButtonListBoxItem}">女</ListBoxItem> <ListBoxItem Style="{StaticResource RadioButtonListBoxItem}">其他</ListBoxItem> <CheckBox>2222333333333333333</CheckBox> <CheckBox>2222333333333333333</CheckBox> <CheckBox>2222333333333333333</CheckBox> <CheckBox>2222333333333333333</CheckBox> <CheckBox>2222333333333333333</CheckBox> <CheckBox>2222333333333333333</CheckBox> <CheckBox>2222333333333333333</CheckBox> <CheckBox>2222333333333333333</CheckBox> <TextBox Width="200"></TextBox> <ListBoxItem IsSelected="True">111</ListBoxItem> </ListBox> <ListBox Margin="5" Grid.Column="1"> <ListBoxItem Style="{StaticResource RadioButtonListBoxItem}">男</ListBoxItem> <ListBoxItem Style="{StaticResource RadioButtonListBoxItem}">女</ListBoxItem> <ListBoxItem Style="{StaticResource RadioButtonListBoxItem}">其他</ListBoxItem> </ListBox> 另外提供一个比较常用的需求,ListBox单选RadioButton效果样式,如上图右边的那个ListBox效果: <Style x:Key="RadioButtonListBoxItem" TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource DefaultListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <Border x:Name="Border" Background="{TemplateBinding Background}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"> <RadioButton IsChecked="{Binding IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"> <RadioButton.Content> <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </RadioButton.Content> </RadioButton> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="Border" Property="Background" Value="{StaticResource ItemSelectedBackground}" /> <Setter Property="Foreground" Value="{StaticResource ItemSelectedForeground}" /> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="Border" Property="Background" Value="{StaticResource ItemMouseOverBackground}" /> <Setter Property="Foreground" Value="{StaticResource ItemMouseOverForeground}" /> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="Border" Property="Opacity" Value="{StaticResource DisableOpacity}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
|
|