滚动条是项目当中经常用到的一个控件,大部分对外项目都有外观的需求,因此需要自定义,文中主要是针对一段动态的状态数据进行展示,并保证数据始终在最新一条,就是需要滚动条滚动到底部。
1,xaml中引入
<ItemsControl Grid.Row="1" Grid.Column="0" ItemsSource="{Binding ProcessList}" ><ItemsControl.ItemTemplate><DataTemplate><!-- 绑定到数组的每个元素 --><TextBlock Text="{Binding }" Foreground="#fff" Margin="4"/></DataTemplate></ItemsControl.ItemTemplate><ItemsControl.Template><ControlTemplate TargetType="ItemsControl"><ScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto" Loaded="ScrollViewer_Loaded" ><ItemsPresenter/></ScrollViewer></ControlTemplate></ItemsControl.Template></ItemsControl>
也可以直接将ScrollViewer放在所用控件的最外层。
VerticalScrollBarVisibility="Auto" 设置为auto可实现超过区域高度自动展示滚动条。
2,具体样式,放到资源中
<Style TargetType="ScrollBar"><Setter Property="Width" Value="8"/><!--设置滚动条宽度--> <Setter Property="Template"><Setter.Value><ControlTemplate TargetType="ScrollBar"><Grid Background="#212222 " Width="14" SnapsToDevicePixels="true" ><Grid.RowDefinitions><!--<RowDefinition Height="Auto"/>--><RowDefinition Height="*"/><!--<RowDefinition Height="Auto"/>--></Grid.RowDefinitions><!--减少按钮--> <!--<RepeatButton Grid.Row="0" Command="ScrollBar.LineUpCommand" Content="^" Width="10" Height="10"/>--><!--轨道和滑块--><Track Grid.Row="1" Name="PART_Track" Width="14" IsDirectionReversed="True"><Track.Thumb><Thumb><Thumb.Template><ControlTemplate><Border CornerRadius="2"><Rectangle Fill="#82E4E4" RadiusX="2" RadiusY="2" Width="6"/><!--<Thumb Width="6" Background="#82E4E4" BorderThickness="0" />--></Border><!--<Rectangle Fill="#82E4E4" Width="8"/>--></ControlTemplate></Thumb.Template></Thumb></Track.Thumb><Track.DecreaseRepeatButton><RepeatButton Command="ScrollBar.PageUpCommand" Opacity="0"/></Track.DecreaseRepeatButton><Track.IncreaseRepeatButton><RepeatButton Command="ScrollBar.PageDownCommand" Opacity="0"/></Track.IncreaseRepeatButton></Track><!--增加按钮--> <!--<RepeatButton Grid.Row="2" Command="ScrollBar.LineDownCommand" Content="v" Width="10" Height="10"/>--></Grid></ControlTemplate></Setter.Value></Setter></Style>
设置样式时候注意点:
IsDirectionReversed="True" 设置为true是保证滚动滑块随着鼠标向下滑动,为false的时候正好相反。
轨道的颜色宽度设置等,直接在Grid上面设置就好。
滑块这里用了个Rectangle,可以设置填充色,圆角、宽度等
我这边不需要上下按钮我就注释掉了。
3,滚动条始终保持在底部,在xaml.cs中实现
需要监听 ProcessList
集合的变化,并在每次添加新项后滚动到 ScrollViewer
的底部。
public partial class F0Procedure : Page{public F0ProcedureViewModel F0ProcedureViewModel { get; set; }private ScrollViewer _scrollViewer;public F0Procedure(){InitializeComponent();F0ProcedureViewModel = new F0ProcedureViewModel();this.DataContext = F0ProcedureViewModel;((INotifyCollectionChanged)F0ProcedureViewModel.ProcessList).CollectionChanged += F0Procedure_CollectionChanged;}private void F0Procedure_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e){if (e.Action == NotifyCollectionChangedAction.Add && _scrollViewer != null){Application.Current.Dispatcher.Invoke(() =>{Console.WriteLine(ScrollViewer.ExtentHeightProperty);_scrollViewer.ScrollToVerticalOffset(_scrollViewer.ExtentHeight);});}}private void ScrollViewer_Loaded(object sender, RoutedEventArgs e){_scrollViewer = sender as ScrollViewer;}}
我这的ProcessList是委托回调更新的,
[ObservableProperty]
private int _progressValue;public void UpdateExecutionProgress(string process)
{Application.Current.Dispatcher.BeginInvoke(new Action(() => ProcessList.Add(process)));
}
可以用 DispatcherTimer模拟,博客里也有讲过,这边都是引用的CommunityToolKit MVVM库。
4,最终结果
用到哪,学到哪,今天又是满满收获的一天。