C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > WPF WrapPanel虚拟化

WPF使用WrapPanel实现虚拟化效果

作者:驚鏵

这篇文章主要为大家详细介绍了如何利用WPF WrapPanel实现虚拟化效果,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下

WrapPanel 实现虚拟化

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

2.Visual Studio 2022;

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

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

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虚拟化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文