重新想象 Windows 8.1 Store Apps (93) - 控件增强: GridView, ListView
作者:webabcd
介绍
重新想象 Windows 8.1 Store Apps 之控件增强
- GridView 和 ListView 每屏显示的数据量多滚动也流畅
- GridViewItemPresenter 和 ListViewItemPresenter 更方便更快速地显示各种状态
- 自定义 GridViewItemPresenter 和 ListViewItemPresenter
示例
1、演示 GridView 和 ListView 的新增特性: GridView 和 ListView 每屏显示的数据量多滚动也流畅
GridViewAndListView/Employee.cs
namespace Windows81.Controls.GridViewAndListView
{
public class Employee
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsMale { get; set; }
}
}
GridViewAndListView/TestData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Windows81.Controls.GridViewAndListView
{
public class TestData
{
/// <summary>
/// 返回一个 Employee 数据集合,测试用
/// </summary>
public static List<Employee> GetEmployees()
{
var employees = new List<Employee>(); for (int i = ; i < ; i++)
{
employees.Add(
new Employee
{
Name = "Name " + i.ToString().PadLeft(, ''),
Age = new Random(i).Next(, ),
IsMale = Convert.ToBoolean(i % )
});
} return employees;
}
}
}
GridViewAndListView/IncrementalData.xaml
<Page
x:Name="pageRoot"
x:Class="Windows81.Controls.GridViewAndListView.IncrementalData"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows81.Controls.GridViewAndListView"
xmlns:common="using:Windows81.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent"> <GridView x:Name="gridView" Margin="120 0 0 0"
ContainerContentChanging="gridView_ContainerContentChanging">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Height="100" Width="100" Background="Blue">
<Rectangle x:Name="placeholderRectangle" Fill="Red" Height="10" Opacity="0" />
<TextBlock x:Name="lblName" Text="{Binding Name}" Foreground="Yellow" />
<TextBlock x:Name="lblAge" Text="{Binding Age}" Foreground="Aqua" />
<TextBlock x:Name="lblIsMale" Text="{Binding IsMale}" Foreground="Gray" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView> </Grid>
</Page>
GridViewAndListView/IncrementalData.xaml.cs
/*
* 演示 GridView 和 ListView 的新增特性
*
* 当 GridView 或 ListView 的一屏需要显示的数据量极大时(一屏的 item 多,且每个 item 中的 element 也多),由于每次滚动时需要绘制当前屏的每个 element,这需要占用大量的 ui 资源,所以就会有一些卡顿
* 为了解决这个问题 win8.1 给出了两种解决方案
* 1、设置 GridView 或 ListView 的 ShowsScrollingPlaceholders 属性为 true(默认值),每次显示 item 时先会显示占位符(application 级的背景色块),然后再绘制内容
* 2、通过 GridView 或 ListView 的 ContainerContentChanging 事件,分步绘制 item 中的 element
*/ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Shapes; namespace Windows81.Controls.GridViewAndListView
{
public sealed partial class IncrementalData : Page
{
public IncrementalData()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
gridView.ItemsSource = TestData.GetEmployees(); // 默认值是 true,即为了保证流畅,每次显示 item 时先会显示占位符(application 级的背景色块),然后再绘制内容
// 本例演示 ContainerContentChanging 事件的使用,所以不会用到这个
gridView.ShowsScrollingPlaceholders = false;
} private void gridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
// 交由我处理吧
args.Handled = true; // 第 1 阶段绘制
// args.Phase.ToString(); // StackPanel templateRoot = (StackPanel)args.ItemContainer.ContentTemplateRoot;
Rectangle placeholderRectangle = (Rectangle)templateRoot.FindName("placeholderRectangle");
TextBlock lblName = (TextBlock)templateRoot.FindName("lblName");
TextBlock lblAge = (TextBlock)templateRoot.FindName("lblAge");
TextBlock lblIsMale = (TextBlock)templateRoot.FindName("lblIsMale"); // 显示自定义占位符(也可以不用这个,而是直接显示 item 的背景)
placeholderRectangle.Opacity = ; // 除了占位符外,所有 item 全部暂时不绘制
lblName.Opacity = ;
lblAge.Opacity = ;
lblIsMale.Opacity = ; // 开始下一阶段的绘制
args.RegisterUpdateCallback(ShowName);
} private void ShowName(ListViewBase sender, ContainerContentChangingEventArgs args)
{
// 第 2 阶段绘制
// args.Phase.ToString(); // Employee employee = (Employee)args.Item;
SelectorItem itemContainer = (SelectorItem)args.ItemContainer;
StackPanel templateRoot = (StackPanel)itemContainer.ContentTemplateRoot;
TextBlock lblName = (TextBlock)templateRoot.FindName("lblName"); // 绘制第 2 阶段的内容
lblName.Text = employee.Name;
lblName.Opacity = ; // 开始下一阶段的绘制
args.RegisterUpdateCallback(ShowAge);
} private void ShowAge(ListViewBase sender, ContainerContentChangingEventArgs args)
{
// 第 3 阶段绘制
// args.Phase.ToString(); // Employee employee = (Employee)args.Item;
SelectorItem itemContainer = (SelectorItem)args.ItemContainer;
StackPanel templateRoot = (StackPanel)itemContainer.ContentTemplateRoot;
TextBlock lblAge = (TextBlock)templateRoot.FindName("lblAge"); // 绘制第 3 阶段的内容
lblAge.Text = employee.Age.ToString();
lblAge.Opacity = ; // 开始下一阶段的绘制
args.RegisterUpdateCallback(ShowIsMale);
} private void ShowIsMale(ListViewBase sender, ContainerContentChangingEventArgs args)
{
// 第 4 阶段绘制
// args.Phase.ToString(); // Employee employee = (Employee)args.Item;
SelectorItem itemContainer = (SelectorItem)args.ItemContainer;
StackPanel templateRoot = (StackPanel)itemContainer.ContentTemplateRoot;
Rectangle placeholderRectangle = (Rectangle)templateRoot.FindName("placeholderRectangle");
TextBlock lblIsMale = (TextBlock)templateRoot.FindName("lblIsMale"); // 绘制第 4 阶段的内容
lblIsMale.Text = employee.IsMale.ToString();
lblIsMale.Opacity = ; // 隐藏自定义占位符
placeholderRectangle.Opacity = ;
}
}
}
2、GridViewItemPresenter 和 ListViewItemPresenter - 用于设置控件的各种状态(win8.1 新引入),比 win8 的方式更方便,且更快(win8 的方式是全部加载完后再显示,win8.1 的此方式是需要的时候才加载)
GridViewAndListView/ItemPresenter.xaml
<Page
x:Class="Windows81.Controls.GridViewAndListView.ItemPresenter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows81.Controls.GridViewAndListView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Page.Resources>
<Style x:Key="MyGridViewItemPresenterTemplate" TargetType="GridViewItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<!--
GridViewItemPresenter 和 ListViewItemPresenter - 用于设置控件的各种状态(win8.1 新引入),比 win8 的方式更方便,且更快(win8 的方式是全部加载完后再显示,win8.1 的此方式是需要的时候才加载)
Margin - item 的 margin
SelectionCheckMarkVisualEnabled - 是否显示选中状态的标记
SelectedBorderThickness - 选中状态的边框粗细
SelectedBackground - 选中状态的边框颜色
CheckBrush - 选中状态的图标(本例就是那个小对勾)
...... - 还有好多好多,看文档吧
-->
<GridViewItemPresenter Margin="10" SelectionCheckMarkVisualEnabled="True" SelectedBorderThickness="3" SelectedBackground="Red" CheckBrush="{ThemeResource ListViewItemCheckThemeBrush}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources> <Grid Background="Transparent">
<GridView x:Name="gridView" Margin="120 0 0 0"
ItemContainerStyle="{StaticResource MyGridViewItemPresenterTemplate}"
SelectionMode="Multiple">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Height="100" Width="100" Background="Blue">
<TextBlock x:Name="lblName" Text="{Binding Name}" Foreground="Yellow" />
<TextBlock x:Name="lblAge" Text="{Binding Age}" Foreground="Aqua" />
<TextBlock x:Name="lblIsMale" Text="{Binding IsMale}" Foreground="Gray" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</Page>
GridViewAndListView/ItemPresenter.xaml.cs
/*
* GridViewItemPresenter 和 ListViewItemPresenter - 用于设置控件的各种状态(win8.1 新引入),比 win8 的方式更方便,且更快(win8 的方式是全部加载完后再显示,win8.1 的此方式是需要的时候才加载)
*/ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace Windows81.Controls.GridViewAndListView
{
public sealed partial class ItemPresenter : Page
{
public ItemPresenter()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
gridView.ItemsSource = TestData.GetEmployees();
}
}
}
3、演示自定义 GridViewItemPresenter 和 ListViewItemPresenter 的使用
GridViewAndListView/MyItemPresenter.cs
/*
* 自定义 GridViewItemPresenter 和 ListViewItemPresenter
*
* 本例演示如何自定义一个 ContentPresenter 类,以用于 GridView(参见:ItemPresenterCustom.xaml)
*/ using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Shapes; namespace Windows81.Controls.GridViewAndListView
{
class MyItemPresenter : ContentPresenter
{
Grid _contentGrid = null; // item 的 grid(数据模板中的 Grid,也就是说要使用本例的这个 ContentPresenter 则数据模板中必须要用 Grid 做容器)
Rectangle _pointerOverBorder = null; // 鼠标经过
Rectangle _focusVisual = null; // 选中 PointerDownThemeAnimation _pointerDownAnimation = null;
Storyboard _pointerDownStoryboard = null; GridView _parentGridView; public MyItemPresenter()
: base()
{
base.Margin = new Thickness();
} protected override void OnApplyTemplate()
{
base.OnApplyTemplate(); var obj = VisualTreeHelper.GetParent(this);
while (!(obj is GridView))
{
obj = VisualTreeHelper.GetParent(obj);
}
_parentGridView = (GridView)obj; _contentGrid = (Grid)VisualTreeHelper.GetChild(this, );
} protected override bool GoToElementStateCore(string stateName, bool useTransitions)
{
base.GoToElementStateCore(stateName, useTransitions); switch (stateName)
{
// 正常状态
case "Normal":
HidePointerOverVisuals();
HideFocusVisuals();
if (useTransitions)
{
StopPointerDownAnimation();
}
break; // 选中状态
case "Focused":
case "PointerFocused":
ShowFocusVisuals();
break; // 取消选中状态
case "Unfocused":
HideFocusVisuals();
break; // 鼠标经过状态
case "PointerOver":
ShowPointerOverVisuals();
if (useTransitions)
{
StopPointerDownAnimation();
}
break; // 鼠标点击状态
case "Pressed":
case "PointerOverPressed":
if (useTransitions)
{
StartPointerDownAnimation();
}
break; default: break;
} return true;
} private void StartPointerDownAnimation()
{
if (_pointerDownStoryboard == null)
CreatePointerDownStoryboard(); _pointerDownStoryboard.Begin();
} private void StopPointerDownAnimation()
{
if (_pointerDownStoryboard != null)
_pointerDownStoryboard.Stop();
} private void ShowFocusVisuals()
{
if (!FocusElementsAreCreated())
CreateFocusElements(); _focusVisual.Opacity = ;
} private void HideFocusVisuals()
{
if (FocusElementsAreCreated())
_focusVisual.Opacity = ;
} private void ShowPointerOverVisuals()
{
if (!PointerOverElementsAreCreated())
CreatePointerOverElements(); _pointerOverBorder.Opacity = ;
} private void HidePointerOverVisuals()
{
if (PointerOverElementsAreCreated())
_pointerOverBorder.Opacity = ;
} private void CreatePointerDownStoryboard()
{
_pointerDownAnimation = new PointerDownThemeAnimation();
Storyboard.SetTarget(_pointerDownAnimation, _contentGrid); _pointerDownStoryboard = new Storyboard();
_pointerDownStoryboard.Children.Add(_pointerDownAnimation);
} private void CreatePointerOverElements()
{
_pointerOverBorder = new Rectangle();
_pointerOverBorder.IsHitTestVisible = false;
_pointerOverBorder.Opacity = ;
_pointerOverBorder.Fill = (SolidColorBrush)_parentGridView.Resources["PointerOverBrush"]; // 此资源要预先在 GridView 中定义 _contentGrid.Children.Insert(_contentGrid.Children.Count, _pointerOverBorder);
} private void CreateFocusElements()
{
_focusVisual = new Rectangle();
_focusVisual.IsHitTestVisible = false;
_focusVisual.Height = ;
_focusVisual.StrokeThickness = ;
_focusVisual.VerticalAlignment = VerticalAlignment.Bottom;
_focusVisual.Fill = (SolidColorBrush)_parentGridView.Resources["FocusBrush"]; // 此资源要预先在 GridView 中定义
_focusVisual.Stroke = (SolidColorBrush)_parentGridView.Resources["FocusBrush"]; // 此资源要预先在 GridView 中定义 _contentGrid.Children.Insert(, _focusVisual);
} private bool FocusElementsAreCreated()
{
return _focusVisual != null;
} private bool PointerOverElementsAreCreated()
{
return _pointerOverBorder != null;
}
}
}
GridViewAndListView/ItemPresenterCustom.xaml
<Page
x:Class="Windows81.Controls.GridViewAndListView.ItemPresenterCustom"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows81.Controls.GridViewAndListView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Page.Resources>
<Style x:Key="MyGridViewItemPresenterTemplate" TargetType="GridViewItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<!--
自定义 GridViewItemPresenter 和 ListViewItemPresenter
关于 GridViewItemPresenter 和 ListViewItemPresenter 的说明参见:ItemPresenter.xaml MyItemPresenter 参见 MyItemPresenter.cs
-->
<local:MyItemPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources> <Grid Background="Transparent">
<GridView x:Name="gridView" Margin="120 0 0 0"
ItemContainerStyle="{StaticResource MyGridViewItemPresenterTemplate}"
SelectionMode="Multiple">
<GridView.Resources>
<!--MyItemPresenter.cs 中需要用到的资源-->
<SolidColorBrush x:Name="PointerOverBrush" Color="#50505050"/>
<SolidColorBrush x:Name="FocusBrush" Color="#ffff0000"/>
</GridView.Resources>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Height="100" Width="100" Background="Blue">
<TextBlock x:Name="lblName" Text="{Binding Name}" Foreground="Yellow" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</Page>
GridViewAndListView/ItemPresenterCustom.xaml.cs
/*
* 演示自定义 GridViewItemPresenter 和 ListViewItemPresenter 的使用
*
* 关于 GridViewItemPresenter 和 ListViewItemPresenter 的说明参见:ItemPresenter.xaml
*/ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace Windows81.Controls.GridViewAndListView
{
public sealed partial class ItemPresenterCustom : Page
{
public ItemPresenterCustom()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
gridView.ItemsSource = TestData.GetEmployees();
}
}
}
OK
[源码下载]
重新想象 Windows 8.1 Store Apps (93) - 控件增强: GridView, ListView的更多相关文章
- 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图
[源码下载] 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Co ...
- 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件增加了 PlaceholderText 属性
[源码下载] 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件 ...
- 重新想象 Windows 8.1 Store Apps (78) - 控件增强: ScrollViewer, FlipView, Popup
[源码下载] 重新想象 Windows 8.1 Store Apps (78) - 控件增强: ScrollViewer, FlipView, Popup 作者:webabcd 介绍重新想象 Wind ...
- 重新想象 Windows 8.1 Store Apps (79) - 控件增强: MediaElement, Frame
[源码下载] 重新想象 Windows 8.1 Store Apps (79) - 控件增强: MediaElement, Frame 作者:webabcd 介绍重新想象 Windows 8.1 St ...
- 重新想象 Windows 8.1 Store Apps (80) - 控件增强: WebView 之基本应用, POST 数据, 与 JavaScript 交互
[源码下载] 重新想象 Windows 8.1 Store Apps (80) - 控件增强: WebView 之基本应用, POST 数据, 与 JavaScript 交互 作者:webabcd 介 ...
- 重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图
原文:重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 Web ...
- 重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示
原文:重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示 [源码下载] 重新想象 Windows 8 Store Ap ...
- 重新想象 Windows 8.1 Store Apps 系列文章索引
[源码下载] [重新想象 Windows 8 Store Apps 系列文章] 重新想象 Windows 8.1 Store Apps 系列文章索引 作者:webabcd 1.重新想象 Windows ...
- 重新想象 Windows 8.1 Store Apps (72) - 新增控件: AppBar, CommandBar
[源码下载] 重新想象 Windows 8.1 Store Apps (72) - 新增控件: AppBar, CommandBar 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...
随机推荐
- 1.什么是泛型和C#中泛型在Class上的实现
阅读目录 一:什么是泛型? 二:C#中泛型在Class上的实现 一:什么是泛型? 我们在编程的时候需要一个数据类型,但是在刚开始的时候还不确定这个数据类型是怎么样的,或者说对于不同的多个数据类型有 ...
- Java IO--压缩流
压缩流: 压缩流的实现: zipEntry: 在实例化ZipEntry的时候,要设置名称,此名称实际上就是压缩文件中的每一个元素的名称. ZipOutputStream: import java.io ...
- ViewPager中使用PhotoView时出现pointerIndex out of range异常
问题描述: 当PhotoView 和 ViewPager 组合时 ,用双指进行放大时 是没有问题的,但是用双指进行缩小的时候,程序就会崩掉,并且抛出java.lang.IllegalArgumentE ...
- android 监听软键盘的收起与打开
参考: http://toughcoder.net/blog/2015/10/09/android-trick-detect-soft-keyboard-show-slash-hide/ packag ...
- MFC一个类访问另一个类成员对象的成员变量值
MFC中一个类要访问另外一个类的的对象的成员变量值,这就需要获得原来那个类对象的指针,其实有好几种方法都可以实现. 比如维护一个单例模式.设置静态变量等等.我们这里举个列子,实现多个类之间的相互访问. ...
- 飞思卡尔9S12X系列双核中的协处理器XGATE使用方法
http://adi.chinaaet.com/analog/blogdetail/24482.html
- 代码生成的地址:mygeneration
一个代码生成的地址: https://gitshell.com/shiningrise/mygeneration/
- POJ 1451 T9
T9 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3083 Accepted: 1101 Description Ba ...
- APP-BOM-20516 错误处理一例
昨天在处理一个工单异常时,需要将一个Released的工单改为Unreleased状态,程序报APP-BOM-20516错误,如下图.百度只搜到两条记录,均无用.Google能搜到的多一些,也无用.进 ...
- 内存调试的东西D/dalvikvm( 809 ): GC_CONCURRENT freed
一般Java虚拟机要求支持verbosegc选项,输出详细的垃圾收集调试信息.dalvik虚拟机很安静的接受verbosegc选项,然后什么都不做.dalvik虚拟机使用自己的一套LOG机制来输出调试 ...