wp8 列表虚拟化异步加载

性能: LongListSelector虚拟化性能比Listbox更好


1、定义Data类

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace 列表虚拟化异步加载
{
    class Data:INotifyPropertyChanged
    {
        //Name属性
        public string Name { get; set; }
        //imageURI属性
        private Uri imageUri;
        public Uri ImageUri
        {
            get { return imageUri; }
            set {
                if (imageUri == value)
                {
                    return; 
                }
                imageUri = value;
                bitmapImage = null;
            }
        }
        //定义弱引用
        WeakReference bitmapImage;
        //ImageSource属性
        public ImageSource ImageSource
        {
            get
            {
                //bitmapImage不等于null
                if (bitmapImage != null)
                {
                    //ImageSource没有被回收
                    if (bitmapImage.IsAlive)
                        //获取当前WeakReference对象,强制转换成ImageSource
                        return (ImageSource)bitmapImage.Target;
                    else
                        Debug.WriteLine("数据已被回收");
                }
                if (imageUri != null)
                {
                    //后台线程 执行DownLoadImage(imageUri)
                    ThreadPool.QueueUserWorkItem(DownLoadImage,imageUri);
                }
                return null;
            }
        }
        void DownLoadImage(object state)
        {
            
            HttpWebRequest request = WebRequest.CreateHttp(state as Uri);
            //异步方法DownLoadImageComplete(request)
            request.BeginGetResponse(DownLoadImageComplete, request);
        }

        void DownLoadImageComplete(IAsyncResult result)
        {
            HttpWebRequest requset = result.AsyncState as HttpWebRequest;
            HttpWebResponse response =(HttpWebResponse)requset.EndGetResponse(result);
            Stream stream = response.GetResponseStream();
            int length = (int)response.ContentLength;
            Stream streamForUi = new MemoryStream(length);
            byte[] buffer = new byte[length];
            int read = 0;
            do
            {
                read = stream.Read(buffer, 0, length);
                streamForUi.Write(buffer, 0, read);
            } while (read == length);
            streamForUi.Seek(0, SeekOrigin.Begin);
            Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    BitmapImage bm = new BitmapImage();
                    bm.SetSource(streamForUi);
                    if (bitmapImage == null)
                        bitmapImage = new WeakReference(bm);
                    else
                        bitmapImage.Target = bm;
                    //触发UI的改变
                    OnpropertyChanged("ImageSource");
                }
            );
        }
        void OnpropertyChanged(string property)
        {
            var hander = PropertyChanged;
            if (hander != null)
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        hander(this, new PropertyChangedEventArgs(property));
                    }
                    );
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

2、UI设计

<phone:PhoneApplicationPage
    x:Class="列表虚拟化异步加载.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">
    <phone:PhoneApplicationPage.Resources>
        <DataTemplate x:Key="ItemTemplate">
            <StackPanel>
                <TextBlock Text="{Binding Name}" Height="80">
                    
                </TextBlock>
                <Image Source="{Binding ImageSource}" Width="200" Height="200">
                    
                </Image>
            </StackPanel>
        </DataTemplate>
    </phone:PhoneApplicationPage.Resources>


        <!--LayoutRoot 是包含所有页面内容的根网格-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- 本地化说明:
            若要本地化显示的字符串,请将其值复制到应用程序的非特定语言资源文件(AppResources.resx)
            中的适当命名的键,然后
            将属性的引号之间的硬编码文本值
            替换为其路径指向该字符串名称的绑定子句。

            例如:

                Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"

            此绑定指向模板的名为“ApplicationTitle”的字符串资源。

            在“项目属性”选项卡中添加受支持的语言将会为
            每种语言创建一个新的 resx 文件,该文件可以包含 UI 字符串的翻译值
            。这些示例中的绑定将导致在运行时从
            与应用程序的 CurrentUICulture 匹配的 .resx 文件中
            提取属性的值。
         -->

        <!--TitlePanel 包含应用程序的名称和页标题-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
            <TextBlock Text="页面名称" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - 在此处放置其他内容-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <phone:LongListSelector x:Name="LongList"
                                    IsGroupingEnabled="False"
                                    LayoutMode="List"
                                    ItemTemplate="{StaticResource ItemTemplate}">
                
            </phone:LongListSelector>
        </Grid>

        <!--取消注释,以显示对齐网格,从而帮助确保
            控件在公用边界上对齐。图像在系统栏中显示时的
            上边距为 -32px。如果隐藏了系统栏,则将此值设为 0
            (或完全删除边距)。

            在发送之前删除此 XAML 和图像本身。-->
        <!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />-->
    </Grid>

</phone:PhoneApplicationPage>

3、主程序调用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using 列表虚拟化异步加载.Resources;

namespace 列表虚拟化异步加载
{
    public partial class MainPage : PhoneApplicationPage
    {
        // 构造函数
        public MainPage()
        {
            InitializeComponent();

            // 用于本地化 ApplicationBar 的示例代码
            //BuildLocalizedApplicationBar();
            List<Data> items=new List<Data>();
            for (int i = 0; i < 1000; i++)
            {
                items.Add(new Data { Name = "Test" + i, ImageUri = new Uri("http://d.hiphotos.baidu.com/image/pic/item/4d086e061d950a7b79bfdfca08d162d9f2d3c932.jpg?Index" + i) });
            }
            LongList.ItemsSource = items;
        }

    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值