WPF使用WrapPanel实现虚拟化效果
WrapPanel 实现虚拟化
1.框架使用大于等于.NET40
;
2.Visual Studio 2022;
3.项目使用 MIT 开源许可协议;
4.众所周知 wpF 的 StackPanel 在加载大量数据时性能会特别差,但是官方提供了一个虚拟化容器VirtualizingStackPanel;
VirtualizingStackPanel.IsVirtualizing
附加属性设置为true
时就开启虚拟化。VirtualizingStackPanel.IsVirtualizing
附加属性设置为false
其VirtualizingStackPanel
行为与普通StackPanel
属性的行为相同。
5.WrapPanel 默认是不支持虚拟化的,所以需要自行实现。
1) VirtualizingWrapPanel 查看源码 | VirtualizingWrapPanel 查看源码。
2) 准备数据HospitalList.cs如下:
usingSystem; usingSystem.Collections.Generic; usingSystem.Collections.ObjectModel; usingSystem.Windows.Media; namespaceWPFDevelopers.Minimal.Sample.Models { publicclassHospitalLisjst:ObservableCollection<Hospital> { publicHospitalList() { varhospitals=newstring[]{"No.189,GroveSt,LosAngeles","No.3669,GroveSt,LosAngeles"}; varnames=newstring[]{"DoctorFang","JudgeQu"}; varimages=newstring[] {"https://pic2.zhimg.com/80/v2-0711e97955adc9be9fbcff67e1007535_720w.jpg", //"https://pic2.zhimg.com/80/v2-5b7f84c63075ba9771f6e6dc29a54615_720w.jpg", "https://pic3.zhimg.com/80/v2-a3d6d8832090520e7ed6c748a8698e4e_720w.jpg", "https://pic3.zhimg.com/80/v2-de7554ac9667a59255fe002bb8753ab6_720w.jpg" }; varstate=0; for(vari=1;i<10000;i++) { Add(newHospital{Id=$"9999{i}",DoctorName=i%2==0?names[0]:names[1],HospitalName=i%2==0?hospitals[0]:hospitals[1],State=state,UserImage=images[state]}); state++; if(state>2) state=0; } } } publicclassHospital { publicstringId{get;set;} publicstringDoctorName{get;set;} publicstringHospitalName{get;set;} publicstringUserImage{get;set;} publicintState{get;set;} } }
3) 新建展示VirtualizingWrapPanelExample.xaml如下:
<ws:Windowx:Class="WPFDevelopers.Minimal.Sample.ExampleViews.VirtualizingWrapPanelExample" 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:ws="https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal" xmlns:local="clr-namespace:WPFDevelopers.Minimal.Sample.ExampleViews" xmlns:model="clr-namespace:WPFDevelopers.Minimal.Sample.Models" xmlns:converts="clr-namespace:WPFDevelopers.Minimal.Sample.Converts" mc:Ignorable="d"WindowStartupLocation="CenterScreen" Title="SystemV1.0"Height="450"Width="900"> <Window.Resources> <model:HospitalListx:Key="myHospitalList"/> <converts:StateConvertx:Key="stateConvert"></converts:StateConvert> </Window.Resources> <GridMargin="4"> <WrapPanelHorizontalAlignment="Left"> <WrapPanel.Resources> <StyleTargetType="Border"> <SetterProperty="Padding"Value="2"></Setter> <SetterProperty="BorderThickness"Value="1"></Setter> </Style> <StyleTargetType="Rectangle"> <SetterProperty="Width"Value="15"></Setter> <SetterProperty="Height"Value="15"></Setter> <SetterProperty="Opacity"Value=".2"></Setter> </Style> </WrapPanel.Resources> <WrapPanel> <BorderBorderBrush="Green"> <RectangleFill="Green"/> </Border> <TextblockText="Idle"Foreground="Black"Margin="4,0"/> </WrapPanel> <WrapPanel> <BorderBorderBrush="Orange"> <RectangleFill="Orange"/> </Border> <TextBlockText="SlightlyIdle"Foreground="Black"Margin="4,0"/> </WrapPanel> <WrapPanel> <BorderBorderBrush="Red"> <RectangleFill="Red"/> </Border> <TextBlockText="Busy"Foreground="Black"Margin="4,0"/> </WrapPanel> </WrapPanel> <TextBlockHorizontalAlignment="Right"Foreground="Black" Margin="4,2"FontSize="16"> <RunText="Count:"></Run> <RunText="{BindingElementName=DocumentsList,Path=.Items.Count,Mode=OneTime}"></Run> </TextBlock> <ListBoxx:Name="DocumentsList" ItemsSource="{BindingSource={StaticResourcemyHospitalList}}" Margin="0,24,0,0"> <ListBox.ItemTemplate> <DataTemplate> <BorderBorderBrush="{BindingState,Converter={StaticResourcestateConvert}}" BorderThickness="1" Width="196" Height="94"> <Grid> <Grid编程.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Rectangle Fill="{BindingState,Converter={StaticResourcestateConvert}}" Opacity=".2"Grid.ColumnSpan="2" Grid.RowSpan="3"/> <BorderGrid.RowSpan="2"Grid.Column="0"Width="60"Height="60" Margin="0,4,0,0"CornerRadius="10"> <Border.Background> <ImageBrushImageSource="{BindingUserImage}"Stretch="Uniform"/> </Border.Background> </Border> <TextBlockGrid.Column="1开发者_开发教程"Grid.Row="0" Text="{BindingPath=Id}"Margin="0,4,0,0"/> <TextBlockGrid.Column="1"Grid.Row="1" Text="{BindingPath=DoctorName}"/> <TextBlockGrid.ColumnSpan="2"Grid.Row="2" Padding="10,0" Text="{BindingPath=HospitalName}"TextTrimming="CharacterEllipsis"/> </Grid> </Border> </DataTemplate> </ListBox.ItemTemplate> <ListBox.Template> <ControlTemplate> <BorderCornerRadius="2" BorderBrush="{TemplateBindingBorderBrush}" BorderThickness="{TemplateBindingBorderThickness}"> <ScrollViewerx:Name="ScrollViewer" Padding="{TemplateBindingPadding}" Background="{TemplateBindingBackground}" BorderBrush="Transparent"BorderThickness="0"IsTabStop="False"> <ItemsPresenter/> </ScrollViewer> </Border> </ControlTemplate> </ListBox.Template> <ListBox.ItemsPanel> <ItemsPanelTemplate> <ws:VirtualizingWrapPanelItemWidth="200" ItemHeight="100"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox> </Grid> </ws:Window>
4) 状态StateConvert.cs如下:
usingSystem; usingSystem.Windows.Data; usingSystem.Windows.Media; namespaceWPFDevelopers.Minimal.Sample.Converts { publicclassStateConvert:IValueConverter { publicobjectConvert(objectvalue,TypetargetType,objectparameter,System.Globalization.CultureInfocultureInfo) { varcolor=Brushes.Green; if(value!=null) { varstate=int.Parse(value.ToString()); switch(state) { case0: color=Brushes.Green; break; case1: color=Brushes.Orange; break; case2: color=Brushes.Red; break; } } returncolor; } publicobjectConvertBack(objectvalue,TypetargetType,objectparameter,System.Globalization.CultureInfocultureInfo) { thrownewNotImplementedException(); } } }
实现效果
到此这篇关于WPF使用WrapPanel实现虚拟化效果的文章就介绍到这了,更多相关WPF WrapPanel虚拟化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
精彩评论