黎正贤 发表于 2023-8-8 18:35:34

WPF自定义TreeView滚动条样式

  根据客户需求,要在TreeView目录树上显示10万+个节点,但是目录树显示10万加节点后,整个页面操作起来非常卡,所以给目录树增加了虚拟化设置。但是虚拟化设置一直没生效,后来经过排查发现是使用的自定义滚动条导致了虚拟化设置没有生效,后来自己写了一个滚动条样式,问题解决了。
目录树虚拟化设置属性
WPF虚拟化技术
https://blog.51cto.com/u_15127512/4364505 属性说明描述VirtualizingStackPanel.IsVirtualizing开启虚拟化属性VirtualizingPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode列表绑定大数据时,显示的速度和流畅性VirtualizingStackPanel.VirtualizationMode="Recycling"ScrollViewer.CanContentScroll设置像素滚动或者单元格滚动设置true 单元滚动,效率更高。ScrollViewer.IsDeferredScrollingEnabled如果用户拖动 Thumb 的 ScrollBar 时内容为静止状态,则为 true;否则为 false。 虚拟化属性 目录树滚动条样式:以下的滚动条样式,是通过原生的滚动条模板样式基础上进行简单修改的,增加了一些注释。<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   
    <SolidColorBrush x:Key="ScrollBar.Static.Background" Color="#F0F0F0"/>
    <SolidColorBrush x:Key="ScrollBar.Static.Border" Color="#F0F0F0"/>
    <SolidColorBrush x:Key="ScrollBar.Static.Glyph" Color="#606060"/>
    <SolidColorBrush x:Key="ScrollBar.Static.Thumb" Color="#CDCDCD"/>
    <SolidColorBrush x:Key="ScrollBar.MouseOver.Background" Color="#DADADA"/>
    <SolidColorBrush x:Key="ScrollBar.MouseOver.Border" Color="#DADADA"/>
    <SolidColorBrush x:Key="ScrollBar.MouseOver.Glyph" Color="#000000"/>
    <SolidColorBrush x:Key="ScrollBar.MouseOver.Thumb" Color="#CCCCCC"/>
    <SolidColorBrush x:Key="ScrollBar.Pressed.Background" Color="#606060"/>
    <SolidColorBrush x:Key="ScrollBar.Pressed.Border" Color="#606060"/>
    <SolidColorBrush x:Key="ScrollBar.Pressed.Thumb" Color="#CCCCCC"/>
    <SolidColorBrush x:Key="ScrollBar.Pressed.Glyph" Color="#FFFFFF"/>
    <SolidColorBrush x:Key="ScrollBar.Disabled.Background" Color="#F0F0F0"/>
    <SolidColorBrush x:Key="ScrollBar.Disabled.Border" Color="#F0F0F0"/>
    <SolidColorBrush x:Key="ScrollBar.Disabled.Glyph" Color="#BFBFBF"/>
   

   
   
   
   
   
   

   
    <ControlTemplate TargetType="{x:Type ScrollBar}" x:Key="VerticalBarTemplate">
      <Grid x:Name="Bg" SnapsToDevicePixels="true">
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
                <RowDefinition Height="0.00001*"/>
                <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
            </Grid.RowDefinitions>
            
            <Border Background="#EDF2FF" BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}" Grid.Row="1"/>
            
            <RepeatButton x:Name="PART_LineUpButton" Command="{x:Static ScrollBar.LineUpCommand}"
                              IsEnabled="{TemplateBinding IsMouseOver}"
                              Style="{StaticResource ScrollBarButton}">
               
                <Path x:Name="ArrowTop" Data="M 0,4 C0,4 0,6 0,6 0,6 3.5,2.5 3.5,2.5 3.5,2.5 7,6 7,6 7,6 7,4 7,4 7,4 3.5,0.5 3.5,0.5 3.5,0.5 0,4 0,4 z" Fill="#CCCCCC" Margin="3,4,3,3" Stretch="Uniform"/>
            </RepeatButton>
            
            <Track x:Name="PART_Track" IsDirectionReversed="true"
                     IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="1">
               
                <Track.DecreaseRepeatButton>
                  
                  <RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Style="{StaticResource RepeatButtonTransparent}"/>
                </Track.DecreaseRepeatButton>
               
                <Track.IncreaseRepeatButton>
                  
                  <RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Style="{StaticResource RepeatButtonTransparent}"/>
                </Track.IncreaseRepeatButton>
               
                <Track.Thumb>
                  <Thumb Style="{StaticResource ScrollBarThumbVertical}"/>
                </Track.Thumb>
            </Track>
            
            <RepeatButton x:Name="PART_LineDownButton" Command="{x:Static ScrollBar.LineDownCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="2" Style="{StaticResource ScrollBarButton}">
               
                <Path x:Name="ArrowBottom" Data="M 0,2.5 C0,2.5 0,0.5 0,0.5 0,0.5 3.5,4 3.5,4 3.5,4 7,0.5 7,0.5 7,0.5 7,2.5 7,2.5 7,2.5 3.5,6 3.5,6 3.5,6 0,2.5 0,2.5 z" Fill="#CCCCCC" Margin="3,4,3,3" Stretch="Uniform"/>
            </RepeatButton>
      </Grid>
      <ControlTemplate.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineDownButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineDownButton}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowBottom" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineUpButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineUpButton}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowTop" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineDownButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineDownButton}" Value="false"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowBottom" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineUpButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineUpButton}" Value="false"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowTop" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
            </MultiDataTrigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Fill" TargetName="ArrowTop" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
                <Setter Property="Fill" TargetName="ArrowBottom" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
            </Trigger>
      </ControlTemplate.Triggers>
    </ControlTemplate>

   
    <ControlTemplate TargetType="{x:Type ScrollBar}" x:Key="HorizontalBarTemplate">
      <Grid x:Name="Bg" SnapsToDevicePixels="true">
            <Grid.ColumnDefinitions>
                <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
                <ColumnDefinition Width="0.00001*"/>
                <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
            </Grid.ColumnDefinitions>
            
            <Border Background="#EDF2FF" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1"/>
            
            <RepeatButton x:Name="PART_LineLeftButton" Command="{x:Static ScrollBar.LineLeftCommand}"
                              IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}">
               
                <Path x:Name="ArrowLeft" Data="M 3.18,7 C3.18,7 5,7 5,7 5,7 1.81,3.5 1.81,3.5 1.81,3.5 5,0 5,0 5,0 3.18,0 3.18,0 3.18,0 0,3.5 0,3.5 0,3.5 3.18,7 3.18,7 z"
                        Fill="#CCCCCC" Margin="3" Stretch="Uniform"/>
            </RepeatButton>
            
            <Track x:Name="PART_Track" Grid.Column="1" IsEnabled="{TemplateBinding IsMouseOver}">
               
                <Track.DecreaseRepeatButton>
                  
                  <RepeatButton Command="{x:Static ScrollBar.PageLeftCommand}" Style="{StaticResource RepeatButtonTransparent}"/>
                </Track.DecreaseRepeatButton>
               
                <Track.IncreaseRepeatButton>
                  
                  <RepeatButton Command="{x:Static ScrollBar.PageRightCommand}" Style="{StaticResource RepeatButtonTransparent}"/>
                </Track.IncreaseRepeatButton>
               
                <Track.Thumb>
                  <Thumb Style="{StaticResource ScrollBarThumbHorizontal}"/>
                </Track.Thumb>
            </Track>
            
            <RepeatButton x:Name="PART_LineRightButton" Command="{x:Static ScrollBar.LineRightCommand}"
                              Grid.Column="2" IsEnabled="{TemplateBinding IsMouseOver}"
                              Style="{StaticResource ScrollBarButton}">
               
                <Path x:Name="ArrowRight" Data="M 1.81,7 C1.81,7 0,7 0,7 0,7 3.18,3.5 3.18,3.5 3.18,3.5 0,0 0,0 0,0 1.81,0 1.81,0 1.81,0 5,3.5 5,3.5 5,3.5 1.81,7 1.81,7 z" Fill="#CCCCCC" Margin="3" Stretch="Uniform"/>
            </RepeatButton>
      </Grid>
      <ControlTemplate.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineRightButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineRightButton}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowRight" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineLeftButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineLeftButton}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowLeft" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineRightButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineRightButton}" Value="false"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowRight" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding IsMouseOver, ElementName=PART_LineLeftButton}" Value="true"/>
                  <Condition Binding="{Binding IsPressed, ElementName=PART_LineLeftButton}" Value="false"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Fill" TargetName="ArrowLeft" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
            </MultiDataTrigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Fill" TargetName="ArrowLeft" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
                <Setter Property="Fill" TargetName="ArrowRight" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
            </Trigger>
      </ControlTemplate.Triggers>
    </ControlTemplate>

   
   

   
</ResourceDictionary>
来源:https://www.cnblogs.com/wjygxjz/archive/2023/08/08/17594253.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: WPF自定义TreeView滚动条样式