WPF使用WrapPanel实现虚拟化效果
作者:驚鏵 时间:2021-07-04 14:53:53
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如下:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Media;
namespace WPFDevelopers.Minimal.Sample.Models
{
public class HospitalList : ObservableCollection<Hospital>
{
public HospitalList()
{
var hospitals = new string[] { "No. 189, Grove St, Los Angeles", "No. 3669, Grove St, Los Angeles" };
var names = new string[] { "Doctor Fang", "Judge Qu" };
var images = new string[]
{ "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"
};
var state = 0;
for (var i = 1; i < 10000; i++)
{
Add(new Hospital { 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;
}
}
}
public class Hospital
{
public string Id { get; set; }
public string DoctorName { get; set; }
public string HospitalName { get; set; }
public string UserImage { get; set; }
public int State { get; set; }
}
}
3) 新建展示VirtualizingWrapPanelExample.xaml如下:
<ws:Window x: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="System V1.0" Height="450" Width="900">
<Window.Resources>
<model:HospitalList x:Key="myHospitalList"/>
<converts:StateConvert x:Key="stateConvert"></converts:StateConvert>
</Window.Resources>
<Grid Margin="4">
<WrapPanel HorizontalAlignment="Left">
<WrapPanel.Resources>
<Style TargetType="Border">
<Setter Property="Padding" Value="2"></Setter>
<Setter Property="BorderThickness" Value="1"></Setter>
</Style>
<Style TargetType="Rectangle">
<Setter Property="Width" Value="15"></Setter>
<Setter Property="Height" Value="15"></Setter>
<Setter Property="Opacity" Value=".2"></Setter>
</Style>
</WrapPanel.Resources>
<WrapPanel>
<Border BorderBrush="Green">
<Rectangle Fill="Green"/>
</Border>
<TextBlock Text="Idle" Foreground="Black" Margin="4,0"/>
</WrapPanel>
<WrapPanel>
<Border BorderBrush="Orange">
<Rectangle Fill="Orange"/>
</Border>
<TextBlock Text="Slightly Idle" Foreground="Black" Margin="4,0"/>
</WrapPanel>
<WrapPanel>
<Border BorderBrush="Red">
<Rectangle Fill="Red"/>
</Border>
<TextBlock Text="Busy" Foreground="Black" Margin="4,0"/>
</WrapPanel>
</WrapPanel>
<TextBlock HorizontalAlignment="Right" Foreground="Black"
Margin="4,2" FontSize="16">
<Run Text="Count:"></Run>
<Run Text="{Binding ElementName=DocumentsList,Path=.Items.Count,Mode=OneTime}"></Run>
</TextBlock>
<ListBox x:Name="DocumentsList"
ItemsSource="{Binding Source={StaticResource myHospitalList}}"
Margin="0,24,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{Binding State,Converter={StaticResource stateConvert}}"
BorderThickness="1"
Width="196"
Height="94">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rectangle
Fill="{Binding State,Converter={StaticResource stateConvert}}"
Opacity=".2" Grid.ColumnSpan="2"
Grid.RowSpan="3"/>
<Border Grid.RowSpan="2" Grid.Column="0" Width="60" Height="60"
Margin="0,4,0,0" CornerRadius="10">
<Border.Background>
<ImageBrush ImageSource="{Binding UserImage}" Stretch="Uniform"/>
</Border.Background>
</Border>
<TextBlock Grid.Column="1" Grid.Row="0"
Text="{Binding Path=Id}" Margin="0,4,0,0"/>
<TextBlock Grid.Column="1" Grid.Row="1"
Text="{Binding Path=DoctorName}"/>
<TextBlock Grid.ColumnSpan="2" Grid.Row="2"
Padding="10,0"
Text="{Binding Path=HospitalName}" TextTrimming="CharacterEllipsis"/>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Template>
<ControlTemplate>
<Border CornerRadius="2"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer x:Name="ScrollViewer"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="Transparent" BorderThickness="0" IsTabStop="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<ws:VirtualizingWrapPanel ItemWidth="200"
ItemHeight="100"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</ws:Window>
4) 状态StateConvert.cs如下:
using System;
using System.Windows.Data;
using System.Windows.Media;
namespace WPFDevelopers.Minimal.Sample.Converts
{
public class StateConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo)
{
var color = Brushes.Green;
if (value != null)
{
var state = int.Parse(value.ToString());
switch (state)
{
case 0:
color = Brushes.Green;
break;
case 1:
color = Brushes.Orange;
break;
case 2:
color = Brushes.Red;
break;
}
}
return color;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo)
{
throw new NotImplementedException();
}
}
}
实现效果
来源:https://mp.weixin.qq.com/s/loyvSipJbLYkcmwBidtisg
标签:WPF,WrapPanel,虚拟化
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
IDEA maven项目中刷新依赖的两种方法小结
2022-10-06 05:52:03
![](https://img.aspxhome.com/file/2023/2/95932_0s.jpg)
Spring Boot多个定时任务阻塞问题的解决方法
2023-09-20 11:43:36
解析spring cloud ouath2中的Eureka
2023-10-12 04:07:54
![](https://img.aspxhome.com/file/2023/6/61006_0s.png)
SpringBoot中使用Session共享实现分布式部署的示例代码
2022-10-17 04:27:54
![](https://img.aspxhome.com/file/2023/7/66687_0s.png)
springboot自定义Starter过程解析
2023-07-24 22:24:55
Spring 4.0新功能:@Conditional注解详细介绍
2022-01-19 06:37:35
基于ElasticSearch Analyzer的使用规则详解
2023-09-28 14:41:04
![](https://img.aspxhome.com/file/2023/8/63698_0s.png)
java实现录音播放功能
2023-03-25 03:38:23
![](https://img.aspxhome.com/file/2023/4/94764_0s.jpg)
android高仿小米时钟(使用Camera和Matrix实现3D效果)
2022-05-15 01:46:18
![](https://img.aspxhome.com/file/2023/3/98633_0s.gif)
微服务分布式架构实现日志链路跟踪的方法
2023-11-29 15:43:16
![](https://img.aspxhome.com/file/2023/3/60123_0s.jpg)
C#使用委托实现的快速排序算法实例
2022-01-22 18:29:52
jQuery.event.trigger()的简单解释
2023-05-24 03:41:37
![](https://img.aspxhome.com/file/2023/2/62232_0s.png)
SpringBoot整合RabbitMQ实现消息确认机制
2023-09-11 04:07:22
![](https://img.aspxhome.com/file/2023/2/108472_0s.png)
JAVA8之函数式编程Function接口用法
2022-01-04 04:03:04
![](https://img.aspxhome.com/file/2023/6/63276_0s.jpg)
Java线程同步、同步方法实例详解
2023-10-16 07:10:53
Java客户端利用Jedis操作redis缓存示例代码
2021-05-31 03:43:42
Java全面细致讲解==和equals的使用
2021-08-20 05:28:43
idea插件之mybatis log plugin控制台sql的问题
2023-05-14 06:45:32
![](https://img.aspxhome.com/file/2023/7/99867_0s.png)
Android 5秒学会使用手势解锁功能
2023-07-11 13:48:32
![](https://img.aspxhome.com/file/2023/1/83511_0s.gif)
springcloud注册hostname或者ip的那些事
2022-05-06 00:57:37
![](https://img.aspxhome.com/file/2023/9/65369_0s.png)