WPF使用WrapPanel实现虚拟化效果

 更新时间:2022年09月19日 08:43:27   作者:驚鏵  
这篇文章主要为大家详细介绍了如何利用WPF WrapPanel实现虚拟化效果,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下

WrapPanel 实现虚拟化

1.框架使用大于等于.NET40

2.Visual Studio 2022;

3.项目使用 MIT 开源许可协议;

4.众所周知 WPF 的 StackPanel 在加载大量数据时性能会特别差,但是官方提供了一个虚拟化容器VirtualizingStackPanel

  • VirtualizingStackPanel.IsVirtualizing 附加属性设置为 true时就开启虚拟化。
  • VirtualizingStackPanel.IsVirtualizing 附加属性设置为 falseVirtualizingStackPanel行为与普通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();
        }
    }
}

实现效果

到此这篇关于WPF使用WrapPanel实现虚拟化效果的文章就介绍到这了,更多相关WPF WrapPanel虚拟化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c# 遍历获取所有文件的示例代码

    c# 遍历获取所有文件的示例代码

    这篇文章主要介绍了c# 遍历获取所有文件的示例代码,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下
    2020-12-12
  • VS2019使用快捷键将代码对齐的方法

    VS2019使用快捷键将代码对齐的方法

    这篇文章主要介绍了VS2019使用快捷键将代码对齐的相关资料,非常不错对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • C#调用QQ_Mail发送邮件实例代码两例

    C#调用QQ_Mail发送邮件实例代码两例

    这篇文章介绍了C#调用QQ_Mail发送邮件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 详析C#的协变和逆变

    详析C#的协变和逆变

    这篇文章主要介绍了详析C#的协变和逆变,在引用类型系统时,协变、逆变和不变性具有如下定义。 这些示例假定一个名为 Base 的基类和一个名为 Derived的派生类,更多内容请需要的小伙伴参考下面文章内容
    2022-01-01
  • 解析.NET中几种Timer的使用

    解析.NET中几种Timer的使用

    本文主要对.NET中4个Timer类,及其用法进行梳理,具有很好参考价值,需要的朋友一起来看下吧
    2016-12-12
  • C#用RabbitMQ实现消息订阅与发布

    C#用RabbitMQ实现消息订阅与发布

    在消息队列模型中,如何将消息广播到所有的消费者,这种模式成为“发布/订阅”。本文主要以一个简单的小例子,简述通过fanout交换机,实现消息的发布与订阅,仅供学习分享使用,如有不足之处,还请指正。
    2021-05-05
  • C# dump系统lsass内存和sam注册表详细

    C# dump系统lsass内存和sam注册表详细

    这篇文章主要介绍了C# dump系统lsass内存和sam注册表,在这里选择 C# 的好处是体积小,结合 loadAssembly 方便免杀,希望对读者们有所帮助
    2021-09-09
  • C# WINFORM自定义异常处理方法

    C# WINFORM自定义异常处理方法

    这篇文章主要介绍了一个简单的统一异常处理方法。系统底层出现异常,写入记录文件,系统顶层捕获底层异常,显示提示信息。需要的可以参考一下
    2021-12-12
  • 分享WCF文件传输实现方法---WCFFileTransfer

    分享WCF文件传输实现方法---WCFFileTransfer

    这篇文章主要介绍了分享WCF文件传输实现方法---WCFFileTransfer,需要的朋友可以参考下
    2015-11-11
  • 详解C# 枚举高级用法之Description

    详解C# 枚举高级用法之Description

    这篇文章主要介绍了C# 枚举高级用法之Description,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02

最新评论