在写 Windows phone应用性能优化(一)的时候,在 ListBox 的项加载的时候,添加了一些简单的动画。

其实在 Windows Phone 的应用中使用 Blend 设计动画是很容易的,并且在程序的交互中,增加一些动画

效果,用户会感觉用户体验非常的好,从而提升了用户对应用的印象评分。

本文的 demo 演示如何逐项的加载列表中的每一项。对于延时迭代加载列表中的项,通常会考虑使用 DispatherTimer,

但是如果设计的逻辑较多,需要的代码量会比较多,并且不好维护。这里使用 Rx(Reactive Extensions) 中的

Observable 类进行对 IObservable<T> 的创建。在 Rx 中 IObservable<T> (可观察序列)和 IObserver<T> (观察者)

是两个核心的元素,我研究了一段时间,感觉它在  .NET 平台是可以大有作为的,它的使用并不难,很多操作使用是以 LINQ

的扩展方法而使用的,重点是理解 (IObservable)的 “推”数据 和 (IEnumerable)的 “拉”数据的 数据源数据流向的不同。

以后还会继续研究的。之前翻译的有关 Rx 一篇文章

这个示例在页面中使用一个 Pivot 控件,两个 PivotItem 项都是使用 ListBox 作为模版,区别是:

1)第一个 PivotItem 项中的 ItemsPanel 模版使用默认的,在第二个 PivotItem 中

的 ListBox 中, 把 ItemsPanel 设置为了 WrapPanel,从而使 Item 可以流动布局:

 <ListBox ItemsSource="{Binding}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Controls:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

2)两个 ListBox 中的 ItemTemplate 中的 StackPanel 在触发 Loaded 事件时,开始的动画不同。

MainPage 页面中 Pivot 控件的全部代码:

    <phone:Pivot SelectionChanged="Pivot_SelectionChanged">
<phone:PivotItem Header="Stack">
<ListBox ItemsSource="{Binding}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stack" Orientation="Horizontal" Margin="10,30,0,0">
<StackPanel.Triggers>
<EventTrigger RoutedEvent="StackPanel.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="-180"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="106"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationZ)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="246"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="0.4"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="0.4"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<StackPanel.RenderTransform>
<CompositeTransform/>
</StackPanel.RenderTransform>
<StackPanel.Projection>
<PlaneProjection/>
</StackPanel.Projection>
<Image VerticalAlignment="Top" Source="{Binding Photo}" Width="150"/>
<TextBlock Text="{Binding Title}" Width="250" Foreground="Wheat" FontSize="25" Margin="10,0,0,0" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PivotItem>
<phone:PivotItem Header="Wrap">
<ListBox ItemsSource="{Binding}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Controls:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stack" Orientation="Horizontal" Margin="10,30,0,0">
<StackPanel.Triggers>
<EventTrigger RoutedEvent="StackPanel.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuarticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="96"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuarticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<StackPanel.Projection>
<PlaneProjection/>
</StackPanel.Projection>
<Image VerticalAlignment="Top" Source="{Binding Photo}" Width="200"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PivotItem>
</phone:Pivot>

程序的运行效果:

在 MainPage 的 C# 页面的主要代码就不贴出来了,和 Windows phone应用性能优化(一) 中的代码基本相同。

重点的代码,是当 Pivot 触发  Pivot_SelectionChanged 事件的时候,逐项加载 ObservableCollection 集合:

  private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ObservableCollection<News> NewsList2 = new ObservableCollection<News>();
this.DataContext = NewsList2; #region 实现 1
//IObservable<long> obser = Observable.Interval(TimeSpan.FromSeconds(0.3)).ObserveOnDispatcher(); //obser.Subscribe((i) =>
//{ // NewsList2.Add(NewsList[(int)i]);
//});
#endregion #region 实现 2 // 方法含义:
// GenerateWithTime(初始值, 循环条件, 传递给 Observer‘观察者’的值, 延迟时间, 迭代)
//
// 类似于 for循环:for(初始值;循环条件;迭代)
IObservable<int> source = Observable.GenerateWithTime(,
i => i < NewsList.Count,
i => i,
i => TimeSpan.FromSeconds(.),
i => i + ); // 在 Dispather 线程,每次接受 source 传递来的 i 值,即下面的 x
source.ObserveOnDispatcher().Subscribe(x =>
{
NewsList2.Add(NewsList[x]);
Debug.WriteLine(x);
}); #endregion
}

把上面的 Observable.GenerateWithTime(...); 方法可以理解成:

  for (int i = ; i < count; i++)
{
// 当然,Observable 的时间延迟是在异步线程中完成的
Thread.Sleep(TimeSpan.FromSeconds(.)); // 逻辑
}

工程 demo 下载

Observable 示例之 Windows Phone 列表内项目逐个加载的更多相关文章

  1. 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

    [源码下载] 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件 作者 ...

  2. wepy小程序实现列表分页上拉加载(2)

    第一篇:wepy小程序实现列表分页上拉加载(1) 本文接着上一篇内容: 4.优化-添加加载动画 (1)首先写加载动画的结构和样式 打开list.wpy文件 template结构代码: <temp ...

  3. wepy小程序实现列表分页上拉加载(1)

    使用wepy开发微信小程序商城第一篇:项目初始化 使用wepy开发微信小程序商城第二篇:路由配置和页面结构 列表页效果图: 1.新建列表页 (1)在pages里面新建一个list.wpy文件 初始代码 ...

  4. quartz.net 项目无法加载的问题

    最近尝试试用一下quartz.net 做任务调度用. 下载了源代码后打开解决方案发现项目无法加载.错误如下 未找到导入的项目“C:\Users\****\Desktop\Quartz.NET-2.1. ...

  5. 微信小程序开发——列表分页上拉加载封装实现(订单列表为例,订单状态改变后刷新列表滚动位置不变)

    业务需求: 业务需求是给订单列表添加分页功能,也就是上拉加载这种每次只请求加载固定数量的数据. 需求分析: 对业务来说就是简单的分页上拉加载,但是对于技术实现来说,除了要处理分页数据的累加加载,还要处 ...

  6. 模块 DLL C:\WINDOWS\system32\inetsrv\aspnetcore.dll 未能加载。返回的数据为错误信息。

    更新了win10的版本后,就启动原来的iis发布的程序 程序池就自动关闭.后来 启动网站 iis程序池自动关闭. 在为应用程序池“.NET v4.5”提供服务的工作进程“21908”中,协议“http ...

  7. 在iframe内页面完全加载完后,关闭父页面生成的div遮罩层

    遮罩层div为iframe父页面生成,需在iframe内页面完全加载完后,关闭遮罩层 alertMsgClose() :函数为关闭遮罩层函数 此段代码在iframe页面内: <script> ...

  8. Springboot项目自动加载设置

    SpringBoot是允许项目自动加载的,但是需要在pom文件映入依赖库 1.导入依赖库 <dependency> <groupId>org.springframework.b ...

  9. Windows Phone 7 ListBox 列表项渐显加载动画学习笔记

    在wp7程序中,当程序功能越来越复杂时,性能问题是我们不得不考虑的一个问题.在聊天列表中,如果聊天项过多,而且项目UI组件足够复杂时, 我们不得不想尽办法让UI尽快加载.所以有一种可行的方案,就是像Q ...

随机推荐

  1. windows安装dcm4chee 出错 check file system group LOSSY_STORAGE for deletion

    错误情景: 解决方法: 更改服务的监听端口(参考DICOM:Ubuntu14环境下安装dcm4chee+oviyam2.1)

  2. ActiveX 控件漏洞挖掘之方法

    ActiveX是微软公司提出,并在1996年被正式命名的组件技术.该技术提供了一种通用的开放程序接口,使用这种技术开发的ActiveX控件可以直接集成到IE浏览器或第三方应用程序中,但由于第三方编程等 ...

  3. 设置tomcat配置文件,在Myeclipse中修改jsp文件之后不用重启tomcat

    在Myeclipse中创建的Web程序在修改类或者jsp页面后需要重动ttomcat的,要重新加载一次的,即重新启动tomcat一次.重启时比较慢,及浪费资源及时间, 设置tomcat配置文件,在My ...

  4. mssql Sqlver 修改标识列方法

    摘自: http://www.cnblogs.com/badboy2008/articles/1145465.html MSSQL Server修改标识列方法   ----允许对系统表进行更新exec ...

  5. Chrome 制作绿色便携版

    1.建立一个新的文件夹命名为Chrome 2.将电脑上默认的Chrome文件复制到新的文件夹Chrome里包含安装文件和Chrome数据文件     Chrome数据文件一般在"C:\Use ...

  6. 免费的多数据库管理工具sqldbx个人版本

    SqlDbx是一个先进的Sql编辑器和数据库对象资源管理器SqlDbx仅一个可执行的文件不需要安装 SqlDbx与SSMS对象内存占差的不是一点点,但功能与SSMS相当 优点:支持多数据库,占用内存小 ...

  7. RDLC 动态列

    很久没有写博客了,关于动态列,国内很少资料有介绍动态列的,所想写点心得给哥们 啥是动态列呢?通常我们用存储过程时有列转行和行转列的做法,那么在RDLC 怎么支持呢?其实很简单,就是利用了RDLC的 C ...

  8. 【转】非教育网中IPv4网络访问IPv6资源

    1. 背景知识 随着个人电脑.移动终端.乃至物联网的不断发展,有很大的IP地址需求.由于IPv4协议设计时没有料到日后网络会如此发达,IPv4网络中的IP数量相对今天的需求来说,显得捉襟见肘.加上IP ...

  9. TensorFlow编译androiddemo

    首先是把tensorflow克隆到本地一份. git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git 既 ...

  10. Java入门到精通——调错篇之Eclipse No Java virtual machine was found after searching the following locations

    一.错误现象. 在一次启动Eclipse的时候弹出了以下的错误 二.错误原因 原因是没有找到javaw.exe文件的路径. 三.解决方式 在eclipse根文件夹下找到eclipse.ini增加以下一 ...