背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter
作者:webabcd
介绍
背水一战 Windows 10 之 控件(集合类 - ItemsControl)
- 自定义 ItemsControl(自定义 GirdView 使其每个 item 占用不同大小的空间)
- 自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
示例
1、自定义 ItemsControl(自定义 GirdView 使其每个 item 占用不同大小的空间)
Controls/CollectionControl/ItemsControlDemo/MyItemsControlDemo.xaml
- <Page
- x:Class="Windows10.Controls.CollectionControl.ItemsControlDemo.MyItemsControlDemo"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="using:Windows10.Controls.CollectionControl.ItemsControlDemo"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d">
- <Page.Resources>
- <DataTemplate x:Key="ItemTemplate">
- <Grid Background="{Binding ColorValue}">
- <Grid Background="Black" VerticalAlignment="Top" Opacity="0.7">
- <TextBlock Text="{Binding ColorName}" />
- </Grid>
- </Grid>
- </DataTemplate>
- <Style x:Key="ItemContainerStyle" TargetType="GridViewItem">
- <Setter Property="VerticalContentAlignment" Value="Stretch" />
- <Setter Property="HorizontalContentAlignment" Value="Stretch" />
- <Setter Property="Margin" Value="0" />
- <Setter Property="Padding" Value="0" />
- </Style>
- <ItemsPanelTemplate x:Key="ItemsPanel">
- <VariableSizedWrapGrid MaximumRowsOrColumns="8" Orientation="Horizontal" ItemWidth="100" ItemHeight="100" />
- </ItemsPanelTemplate>
- </Page.Resources>
- <Grid Background="Transparent" Margin="10 0 10 10">
- <!--
- 使用 MyGridView 控件,其重写了 GridView 的 PrepareContainerForItemOverride() 方法,详见 MyGridView.cs
- -->
- <local:MyGridView x:Name="gridView" Width="812" VerticalAlignment="Top" HorizontalAlignment="Left"
- ItemTemplate="{StaticResource ItemTemplate}"
- ItemContainerStyle="{StaticResource ItemContainerStyle}"
- ItemsPanel="{StaticResource ItemsPanel}"
- IsItemClickEnabled="False"
- SelectionMode="None">
- </local:MyGridView>
- </Grid>
- </Page>
Controls/CollectionControl/ItemsControlDemo/MyItemsControlDemo.xaml.cs
- /*
- * ItemsControl - 集合控件(继承自 Control, 请参见 /Controls/BaseControl/ControlDemo/)
- * protected virtual void PrepareContainerForItemOverride(DependencyObject element, object item); - 为 item 准备 container 时
- * element - item 的 container
- * item - item
- *
- *
- * 本例用于演示如何使 GirdView 中的每个 item 占用不同大小的空间
- * 1、布局控件要使用 VariableSizedWrapGrid(利用其 RowSpan 和 ColumnSpan 来实现 item 占用不同大小的空间),需要注意的是其并非是虚拟化布局控件
- * 2、自定义 GridView,并重写 ItemsControl 的 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 方法
- * 然后设置每个 item 的 VariableSizedWrapGrid.RowSpan 和 VariableSizedWrapGrid.ColumnSpan
- */
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Windows.UI;
- using Windows.UI.Xaml;
- using Windows.UI.Xaml.Controls;
- using Windows.UI.Xaml.Media;
- using System.Reflection;
- namespace Windows10.Controls.CollectionControl.ItemsControlDemo
- {
- public sealed partial class MyItemsControlDemo : Page
- {
- public MyItemsControlDemo()
- {
- this.InitializeComponent();
- BindData();
- }
- private void BindData()
- {
- Random random = new Random();
- // 获取 Windows.UI.Colors 的全部数据
- Type type = typeof(Colors);
- List<ColorModel> colors = type.GetRuntimeProperties() // GetRuntimeProperties() 在 System.Reflection 命名空间下
- .Select(c => new ColorModel
- {
- ColorName = c.Name,
- ColorValue = new SolidColorBrush((Color)c.GetValue(null)),
- ColSpan = random.Next(, ), // 此对象所占网格的列合并数
- RowSpan = random.Next(, ) // 此对象所占网格的行合并数
- })
- .ToList();
- // 绑定数据
- gridView.ItemsSource = colors;
- }
- }
- /// <summary>
- /// 用于数据绑定的对象
- /// </summary>
- public class ColorModel
- {
- public string ColorName { get; set; }
- public SolidColorBrush ColorValue { get; set; }
- // 此对象所占的网格的列合并数
- public int ColSpan { get; set; }
- // 此对象所占的网格的行合并数
- public int RowSpan { get; set; }
- }
- /// <summary>
- /// 自定义 GridView,重写 ItemsControl 的 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 方法
- /// 用于指定 GridView 的每个 item 所占网格的列合并数和行合并数
- /// </summary>
- public class MyGridView : GridView
- {
- protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
- {
- try
- {
- // 设置每个 item 的 VariableSizedWrapGrid.RowSpan 和 VariableSizedWrapGrid.ColumnSpan, 从而实现每个 item 占用不同大小的空间
- // 仅为演示用,由于这里的 ColSpan 和 RowSpan 都是随机计算的,所以可能会出现空白空间
- dynamic dynamicItem = item;
- element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, dynamicItem.ColSpan);
- element.SetValue(VariableSizedWrapGrid.RowSpanProperty, dynamicItem.RowSpan);
- }
- catch (Exception ex)
- {
- var ignore = ex;
- // 当有异常情况发生时(比如:item 没有 ColSpan 属性或 RowSpan 属性)
- element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, );
- element.SetValue(VariableSizedWrapGrid.RowSpanProperty, );
- }
- finally
- {
- base.PrepareContainerForItemOverride(element, item);
- }
- }
- }
- }
2、自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
Controls/CollectionControl/ItemsControlDemo/MyItemPresenter.cs
- /*
- * 自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
- */
- using System;
- using Windows.Foundation;
- using Windows.UI;
- 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 Windows10.Controls.CollectionControl.ItemsControlDemo
- {
- class MyItemPresenter : ContentPresenter
- {
- Panel _container = null; // item 的容器(即在 DataTemplate 中定义的根元素,在示例 MyItemPresenterDemo.xaml 中用的是 Grid)
- Rectangle _pointerOverBorder = null; // 鼠标经过 item 时覆盖在 item 上的 rectangle
- Rectangle _focusVisual = null; // 选中 item 时覆盖在 item 上的 rectangle
- Storyboard _pointerDownStoryboard = null; // 鼠标按下时的动画
- Storyboard _pointerUpStoryboard = null; // 鼠标抬起时的动画
- public MyItemPresenter()
- : base()
- {
- base.Margin = new Thickness();
- }
- // override OnApplyTemplate() - 应用控件模板时调用
- protected override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- _container = (Panel)VisualTreeHelper.GetChild(this, );
- }
- // override GoToElementStateCore() - VisualState 转换时调用(此方法仅在自定义 ContentPresenter 并将其应用于 GridView 或 ListView 的 ItemContainerStyle 时才会被调用)
- // stateName - VisualState 的名字
- // useTransitions - 是否使用 VisualTransition 过渡效果
- protected override bool GoToElementStateCore(string stateName, bool useTransitions)
- {
- base.GoToElementStateCore(stateName, useTransitions);
- switch (stateName)
- {
- // 正常状态
- case "Normal":
- HidePointerOverVisuals();
- HideFocusVisuals();
- if (useTransitions)
- {
- StopPointerDownAnimation();
- }
- break;
- // 选中状态
- case "Selected":
- case "PointerFocused":
- ShowFocusVisuals();
- if (useTransitions)
- {
- StopPointerDownAnimation();
- }
- break;
- // 取消选中状态
- case "Unfocused":
- HideFocusVisuals();
- break;
- // 鼠标经过状态
- case "PointerOver":
- ShowPointerOverVisuals();
- if (useTransitions)
- {
- StopPointerDownAnimation();
- }
- break;
- // 鼠标点击状态
- case "Pressed":
- case "PressedSelected":
- if (useTransitions)
- {
- StartPointerDownAnimation();
- }
- break;
- default: break;
- }
- return true;
- }
- private void StartPointerDownAnimation()
- {
- if (_pointerDownStoryboard == null)
- CreatePointerDownStoryboard();
- _pointerDownStoryboard.Begin();
- }
- private void StopPointerDownAnimation()
- {
- if (_pointerUpStoryboard == null)
- CreatePointerUpStoryboard();
- _pointerUpStoryboard.Begin();
- }
- 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()
- {
- /*
- * 用这种方式为 item 实现鼠标按下的效果会报错(Attempted to read or write protected memory. This is often an indication that other memory is corrupt.),不知道为什么
- * PointerDownThemeAnimation pointerDownAnimation = new PointerDownThemeAnimation();
- * Storyboard.SetTarget(pointerDownAnimation, _container);
- * Storyboard pointerDownStoryboard = new Storyboard();
- * pointerDownStoryboard.Children.Add(pointerDownAnimation);
- */
- DoubleAnimation da1 = new DoubleAnimation()
- {
- To = 0.9,
- Duration = TimeSpan.FromMilliseconds()
- };
- DoubleAnimation da2 = new DoubleAnimation()
- {
- To = 0.9,
- Duration = TimeSpan.FromMilliseconds()
- };
- Storyboard.SetTarget(da1, _container);
- Storyboard.SetTargetProperty(da1, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)");
- Storyboard.SetTarget(da2, _container);
- Storyboard.SetTargetProperty(da2, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)");
- if (!(_container.RenderTransform is TransformGroup))
- {
- TransformGroup Group = new TransformGroup();
- Group.Children.Add(new ScaleTransform());
- _container.RenderTransform = Group;
- _container.RenderTransformOrigin = new Point(0.5, 0.5);
- }
- _pointerDownStoryboard = new Storyboard();
- _pointerDownStoryboard.Children.Add(da1);
- _pointerDownStoryboard.Children.Add(da2);
- _pointerDownStoryboard.Begin();
- }
- private void CreatePointerUpStoryboard()
- {
- DoubleAnimation da1 = new DoubleAnimation()
- {
- To = ,
- Duration = TimeSpan.FromMilliseconds()
- };
- DoubleAnimation da2 = new DoubleAnimation()
- {
- To = ,
- Duration = TimeSpan.FromMilliseconds()
- };
- Storyboard.SetTarget(da1, _container);
- Storyboard.SetTargetProperty(da1, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)");
- Storyboard.SetTarget(da2, _container);
- Storyboard.SetTargetProperty(da2, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)");
- if (!(_container.RenderTransform is TransformGroup))
- {
- TransformGroup Group = new TransformGroup();
- Group.Children.Add(new ScaleTransform());
- _container.RenderTransform = Group;
- _container.RenderTransformOrigin = new Point(0.5, 0.5);
- }
- _pointerUpStoryboard = new Storyboard();
- _pointerUpStoryboard.Children.Add(da1);
- _pointerUpStoryboard.Children.Add(da2);
- _pointerUpStoryboard.Begin();
- }
- private void CreatePointerOverElements()
- {
- _pointerOverBorder = new Rectangle();
- _pointerOverBorder.IsHitTestVisible = false;
- _pointerOverBorder.Opacity = ;
- // 这里把颜色写死了,仅为演示用,实际写的时候要摘出来写成依赖属性
- _pointerOverBorder.Fill = new SolidColorBrush(Color.FromArgb(0x50, 0x50, 0x50, 0x50));
- _container.Children.Insert(_container.Children.Count, _pointerOverBorder);
- }
- private void CreateFocusElements()
- {
- _focusVisual = new Rectangle();
- _focusVisual.IsHitTestVisible = false;
- _focusVisual.Height = ;
- _focusVisual.VerticalAlignment = VerticalAlignment.Bottom;
- // 这里把颜色写死了,仅为演示用,实际写的时候要摘出来写成依赖属性
- _focusVisual.Fill = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0x0, 0x0));
- _container.Children.Insert(, _focusVisual);
- }
- private bool FocusElementsAreCreated()
- {
- return _focusVisual != null;
- }
- private bool PointerOverElementsAreCreated()
- {
- return _pointerOverBorder != null;
- }
- }
- }
Controls/CollectionControl/ItemsControlDemo/MyItemPresenterDemo.xaml
- <Page
- x:Class="Windows10.Controls.CollectionControl.ItemsControlDemo.MyItemPresenterDemo"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="using:Windows10.Controls.CollectionControl.ItemsControlDemo"
- 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">
- <!--
- 自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
- -->
- <local:MyItemPresenter />
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- </Page.Resources>
- <Grid Background="Transparent">
- <GridView x:Name="gridView" SelectionMode="Single" Margin="10 0 10 10"
- ItemContainerStyle="{StaticResource MyGridViewItemPresenterTemplate}">
- <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>
Controls/CollectionControl/ItemsControlDemo/MyItemPresenterDemo.xaml.cs
- /*
- * 本例用于演示如何自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
- */
- using Windows.UI.Xaml.Controls;
- using Windows.UI.Xaml.Navigation;
- using Windows10.Common;
- namespace Windows10.Controls.CollectionControl.ItemsControlDemo
- {
- public sealed partial class MyItemPresenterDemo : Page
- {
- public MyItemPresenterDemo()
- {
- this.InitializeComponent();
- }
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- gridView.ItemsSource = TestData.GetEmployees();
- }
- }
- }
OK
[源码下载]
背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter的更多相关文章
- 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresenter, ListViewItemPresenter
[源码下载] 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresen ...
- 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组
[源码下载] 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组 作者:webabcd 介绍背水一战 Windows 10 之 控件 ...
- 背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid
[源码下载] 背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid 作者:webabc ...
- 背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingStackPanel, WrapGrid
[源码下载] 背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingS ...
- 背水一战 Windows 10 (49) - 控件(集合类): Pivot, Hub
[源码下载] 背水一战 Windows 10 (49) - 控件(集合类): Pivot, Hub 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类) Pivot Hub 示 ...
- 背水一战 Windows 10 (48) - 控件(集合类): FlipView
[源码下载] 背水一战 Windows 10 (48) - 控件(集合类): FlipView 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类) FlipView 示例Fl ...
- 背水一战 Windows 10 (55) - 控件(集合类): SemanticZoom, ISemanticZoomInformation
[源码下载] 背水一战 Windows 10 (55) - 控件(集合类): SemanticZoom, ISemanticZoomInformation 作者:webabcd 介绍背水一战 Wind ...
- 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项
[源码下载] 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合 ...
- 背水一战 Windows 10 (57) - 控件(集合类): ListViewBase - 增量加载, 分步绘制
[源码下载] 背水一战 Windows 10 (57) - 控件(集合类): ListViewBase - 增量加载, 分步绘制 作者:webabcd 介绍背水一战 Windows 10 之 控件(集 ...
随机推荐
- 7-性能测试i报告
性能测试报告概述 1.测试报告是指把测试的过程和结果写成文档:对发现的问题和缺陷进行分析:为纠正软件的存在的质量问题提供依据: 为软件验收和交付打下基础 2.性能测试报告属于软件测试报告的一种,主要针 ...
- DataTable xml 互相转换
//测试方法 public static DataTable Test() { string savePath = System.AppDomain.CurrentDomain.BaseDirecto ...
- ios蓝牙自定义快捷键
http://www.paopaoche.net/app/12072.html Beekeyboard
- oracle 大量连接导致数据库不能登录
系统遇到过几次这种问题,一个系统申请的session数过大,导致数据库进程数满,无法连接的问题. pl sql develope 报的错误是:ORA-12170:TNS:链接超时 oracle用户登录 ...
- Java 学习之集合类(Collections)
Collection(集合类) 我们是使用数组来保存数据,但是他的长度一旦创建,就已经确定了,当我们要动态传入穿值,数组就有些局限了,集合类就孕育而生:所谓集合,就是来保存,盛装数据,也可称为容器类: ...
- 构造函数的prototype和constructor属性
Car.prototype = { name:'BMW', height:1400, long:4900 } function Car(color,owner){ this.color = color ...
- visual studio的试用版评估期已结束 解决办法
启动visual studio 2008后显示对话框:visual studio的试用版评估期已结束.下面有两个按钮,点第一个链接到微软网页,第二个直接关闭.虽然大多数高手已经知道如何解决,但对菜鸟来 ...
- ubuntu server 在 virtualbox中安装增强包
原文链接:http://luzl.iteye.com/blog/1010597 首先说下增强包能干什么,在desktop下面有了增强包桌面就能变大了,在server下也是类似,那个黑屏就能变大了,还有 ...
- vue+大文件分片上传
最近公司在使用vue做工程项目,实现大文件分片上传. 网上找了一天,发现网上很多代码都存在很多问题,最后终于找到了一个符合要求的项目. 工程如下: 对项目的大文件上传功能做出分析,怎么实现大文件分片上 ...
- nginx调优操作之nginx隐藏其版本号
1.nginx下载 下载网址:nginx.org 2.解压nginx [root@iZwz9cl4i8oy1reej7o8pmZ soft]# ls nginx-.tar.gz [root@iZwz9 ...