WinRT ListView间隔变色(二)
上文说到,WinRt中,我们不能在Style的Setter使用Binding.这个问题其实从SL5之前,一直都不可以。但是,为了使用强大的Binding,人们也一直想使用各种方法来达到Binding
从茫茫的Web里找一个有用的东西,本来是很简单的一件事,但是,MS最近几年,经常自我革新,革自己的命,经常今天可以用的技术,明天换个名字,少点东西,就出来让万千小白来试了。从WPF/SL/WinRT一样的Xaml却不一样的精彩。我们常常想,要是WinRT的Xmal也如WPF的那么强大就好了。但这也是只是想想而已。
言归正传
在SL时代,我们参看的一般是这一文章
在WinRT时代,我们借助于SO,找到这个
WinRT : Simple ScheduleControl
另外还一个C++/DX用的
WinRT and C++/CX compatible way to set Bindings via Styles
在这里我们找到一直以来想要的一个帮助类SetterValueBindingHelper
.
如下:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Markup; namespace SLWeek.Utils
{
[ContentProperty(Name = "Values")]
public class SetterValueBindingHelper
{
/// <summary>
/// Optional type parameter used to specify the type of an attached
/// DependencyProperty as an assembly-qualified name, full name, or
/// short name.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods",
Justification = "Unambiguous in XAML.")]
public string Type { get; set; } /// <summary>
/// Property name for the normal/attached DependencyProperty on which
/// to set the Binding.
/// </summary>
public string Property { get; set; } /// <summary>
/// Binding to set on the specified property.
/// </summary>
public Binding Binding { get; set; } /// <summary>
/// Collection of SetterValueBindingHelper instances to apply to the
/// target element.
/// </summary>
/// <remarks>
/// Used when multiple Bindings need to be applied to the same element.
/// </remarks>
public Collection<SetterValueBindingHelper> Values
{
get
{
// Defer creating collection until needed
if (null == _values)
{
_values = new Collection<SetterValueBindingHelper>();
}
return _values;
}
} private Collection<SetterValueBindingHelper> _values; /// <summary>
/// Gets the value of the PropertyBinding attached DependencyProperty.
/// </summary>
/// <param name="element">Element for which to get the property.</param>
/// <returns>Value of PropertyBinding attached DependencyProperty.</returns>
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters",
Justification = "SetBinding is only available on FrameworkElement.")]
public static SetterValueBindingHelper GetPropertyBinding(FrameworkElement element)
{
if (null == element)
{
throw new ArgumentNullException("element");
}
return (SetterValueBindingHelper)element.GetValue(PropertyBindingProperty);
} /// <summary>
/// Sets the value of the PropertyBinding attached DependencyProperty.
/// </summary>
/// <param name="element">Element on which to set the property.</param>
/// <param name="value">Value forPropertyBinding attached DependencyProperty.</param>
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters",
Justification = "SetBinding is only available on FrameworkElement.")]
public static void SetPropertyBinding(FrameworkElement element, SetterValueBindingHelper value)
{
if (null == element)
{
throw new ArgumentNullException("element");
}
element.SetValue(PropertyBindingProperty, value);
} /// <summary>
/// PropertyBinding attached DependencyProperty.
/// </summary>
public static readonly DependencyProperty PropertyBindingProperty =
DependencyProperty.RegisterAttached(
"PropertyBinding",
typeof(SetterValueBindingHelper),
typeof(SetterValueBindingHelper),
new PropertyMetadata(null, OnPropertyBindingPropertyChanged)); /// <summary>
/// Change handler for the PropertyBinding attached DependencyProperty.
/// </summary>
/// <param name="d">Object on which the property was changed.</param>
/// <param name="e">Property change arguments.</param>
private static void OnPropertyBindingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Get/validate parameters
var element = (FrameworkElement)d;
var item = (SetterValueBindingHelper)(e.NewValue); if ((null == item.Values) || ( == item.Values.Count))
{
// No children; apply the relevant binding
ApplyBinding(element, item);
}
else
{
// Apply the bindings of each child
foreach (var child in item.Values)
{
if ((null != item.Property) || (null != item.Binding))
{
throw new ArgumentException(
"A SetterValueBindingHelper with Values may not have its Property or Binding set.");
}
if ( != child.Values.Count)
{
throw new ArgumentException(
"Values of a SetterValueBindingHelper may not have Values themselves.");
}
ApplyBinding(element, child);
}
}
} /// <summary>
/// Applies the Binding represented by the SetterValueBindingHelper.
/// </summary>
/// <param name="element">Element to apply the Binding to.</param>
/// <param name="item">SetterValueBindingHelper representing the Binding.</param>
private static void ApplyBinding(FrameworkElement element, SetterValueBindingHelper item)
{
if ((null == item.Property) || (null == item.Binding))
{
throw new ArgumentException(
"SetterValueBindingHelper's Property and Binding must both be set to non-null values.");
} // Get the type on which to set the Binding
Type type = null;
TypeInfo typeInfo = null;
if (null == item.Type)
{
// No type specified; setting for the specified element
type = element.GetType();
typeInfo = type.GetTypeInfo();
}
else
{
// Try to get the type from the type system
type = System.Type.GetType(item.Type);
if (null == type)
{
// Search for the type in the list of assemblies
foreach (var assembly in AssembliesToSearch)
{
// Match on short or full name
typeInfo = assembly.DefinedTypes
.Where(t => (t.FullName == item.Type) || (t.Name == item.Type))
.FirstOrDefault();
if (null != typeInfo)
{
// Found; done searching
break;
}
}
if (null == typeInfo)
{
// Unable to find the requested type anywhere
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
"Unable to access type \"{0}\". Try using an assembly qualified type name.",
item.Type));
}
}
else
{
typeInfo = type.GetTypeInfo();
}
} // Get the DependencyProperty for which to set the Binding
DependencyProperty property = null;
var field = typeInfo.GetDeclaredProperty(item.Property + "Property"); // type.GetRuntimeField(item.Property + "Property");
if (null != field)
{
property = field.GetValue(null) as DependencyProperty;
}
if (null == property)
{
// Unable to find the requsted property
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
"Unable to access DependencyProperty \"{0}\" on type \"{1}\".",
item.Property, type.Name));
} // Set the specified Binding on the specified property
element.SetBinding(property, item.Binding);
} /// <summary>
/// Returns a stream of assemblies to search for the provided type name.
/// </summary>
private static IEnumerable<Assembly> AssembliesToSearch
{
get
{
// Start with the System.Windows assembly (home of all core controls)
yield return typeof(Windows.UI.Xaml.Controls.Control).GetTypeInfo().Assembly;
}
}
}
}
在这里我们要注册一点:
var field = typeInfo.GetDeclaredProperty(item.Property + "Property");
我们要清楚,依赖属性的问题,我们当前的typeInfo,他可能有的DeclaredProperty,很多是从基类继承过来的。所以,我们在使用的时候,在Xmal中设定SetterValueBindingHelper
的Type是,一定要设定为基类。要不,就不能正常获得依赖属性
我们解决了Setter不能Binding的问题。
接下来,就完成间隔变色的问题
我们先要实现一个Conveter
public sealed class ListItemBackgroudConverter:IValueConverter
{
public SolidColorBrush OddColorBrush { get; set; }
public SolidColorBrush EvenColorBrush { get; set; }
public object Convert(object value, Type targetType, object parameter, string language)
{
var item = value as ListViewItem;
if (item != null)
{
var listView = ItemsControl.ItemsControlFromItemContainer(item);
if (listView != null)
{
var index = listView.IndexFromContainer(item);
return index % == ? EvenColorBrush : OddColorBrush;
}
} return null;
} public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
这个是我们的老套路了,为了方便在XMAL设定间隔色,我们定义了两种Brush
接下来,我们来定义Convetert和ListItem的ItemContainerStyle
<converter:ListItemBackgroudConverter x:Key="ListItemBackgroudConverter" OddColorBrush="{StaticResource SilverColorBrush}" EvenColorBrush="{StaticResource AsbestosColorBrush}"/>
<Style x:Key="ListItemBackgroud" TargetType="ListViewItem">
<Setter Property="utils:SetterValueBindingHelper.PropertyBinding">
<Setter.Value>
<utils:SetterValueBindingHelper Type="Control" Property="Background" Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource ListItemBackgroudConverter}}"/>
</Setter.Value>
</Setter>
</Style>
再一次提醒注意,这里的Type是Control,而不是ListViewItem,因为只有Control的DeclaredProperty才有Backgroud.
我们在页面应用下这个Style
<ListView ItemsSource="{Binding ListPostTypes,Mode=TwoWay}" ItemContainerStyle="{StaticResource ListItemBackgroud}" Style="{StaticResource ListViewWrapItemsPanel}" ItemTemplate="{StaticResource SelectChannelTypeDataTemplate}"/>
最后,我们看下效果:
由于我ListView的Style对ListView的容器进行了更改,换成了ItemsWrapGrid,所以,它会自动根据宽度进行排列
其Style为
<Style x:Key="ListViewWrapItemsPanel" TargetType="ListView">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
WinRT ListView间隔变色(二)的更多相关文章
- WinRT ListView间隔变色(一)
我们知道,在WPF里,MSDN提供了三种方法 1.使用转换器Converter 2.继承ListView类,自己处理 3.使用StyleSelctor 到了WinRT的世界了 1. Winrt中Set ...
- 【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法
原文网址:http://blog.csdn.net/harvic880925/article/details/40475367 前言:前一篇文章给大家展示了传统的Listview的写法,但有的时候我们 ...
- Android ListView 之 SimpleAdapter 二 (包含 item 中按钮监听)
1 MainActivity.java package com.myadapter; import java.util.ArrayList; import java.util.HashMap; ...
- wpf listview 行变色
<ListView x:Name="listView_Date" Grid.Row="3" BorderBrush="{x:Null}" ...
- ListView间隔设置颜色
在Adapter的getView中 if (position % 2 == 0) holder.shoucangbt.setBackgroundColor( Color.rgb(246, 246, 2 ...
- Windows 8.1中WinRT的变化(二)——新增功能
首先我们来看看现有控件中新增的功能: FlipView编程方式切换时支持平滑滚动: 在Windows8中,FlipView在用手触控翻页的时候是有动画效果的,但当我们使用键盘或代码编程翻页时,却没有这 ...
- UI控件之ListView
一,一个简单的TextView列表 public class FirstActivity extends Activity { private String[] data = {"Apple ...
- 【实战】初识ListView及提高效率
简介: ListView是手机上最常用的控件之一,几乎所有的程序都会用到,手机屏幕空间有限,当需要显示大量数据的时候,就需要借助ListView来实现,允许用户通过手指上下滑动的方式将屏幕外的数据滚动 ...
- (转)解决ScrollView嵌套ListView或者GridView导致只显示一行的方法
即动态获取ListView和GridView的高度 一.对于ListView ListView listview= new ListView(this); setListViewHeightBased ...
随机推荐
- UVa 10950 - Bad Code
题目:有一种编码方式.串仅仅有小写字母构成,每一个小写字母相应一个数字,如今给你妆化后的数字串, 问有多少个原串与之相应,注意数字串里可能有一个前导0. 分析:搜索.按字母顺序存储映射表,按字母顺序匹 ...
- openstack (4)---部署Glance镜像服务,Nova计算服务
一.Glance Glance是Openstack项目中负责镜像管理的模块,其功能包括虚拟机镜像的查找.注册和检索等. Glance提供Restful API可以查询虚拟机镜像的metadata及获取 ...
- PHP导入和导出CSV文件
CREATE TABLE `student` ( `id` ) NOT NULL auto_increment, `name` varchar() NOT NULL, `sex` varchar() ...
- Cookies 初识 Dotnetspider EF 6.x、EF Core实现dynamic动态查询和EF Core注入多个上下文实例池你知道有什么问题? EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)
Cookies 1.创建HttpCookies Cookie=new HttpCookies("CookieName");2.添加内容Cookie.Values.Add(&qu ...
- python开发【第1篇】【基础知识】
1.python解释执行原理 python代码——字节码——机器码——计算机 每次运行都要进行转换成字节码,然后再有虚拟机把字节码转换成机器语言,最后才能在硬件上运行. 2.python编码 unic ...
- H264--3--NAL层的处理[6]
------------------------------H.264的NAL层处理 ------------------------------ H264以NALU(NAL unit)为单位来支持编 ...
- swift中使用GCDMulticastDelegate
在开源库XMPPFramework中提供了一个GCDMulticastDelegate类,使用它可以为一个对象添加多个被委托的对象,以前用oc编写的工程引入了这个类,使用起来十分方便.最近由于换了工作 ...
- 使用nginx搭建媒体点播服务器
使用nginx搭建媒体点播服务器 最新由于兴趣,对ubuntu和安卓上的视频点播直播等应用比较感兴趣,所以在vmware的虚拟机里面搭建了一个视频点播网站,参考了fengzhanhai的文章Nginx ...
- 将属性和方法添加到Date原型中
<button onclick="myFunction()">点我</button> <script> Date.prototype.myMet ...
- System.Drawing.Color的几种使用方法
System.Drawing.Color cl = Color.Red; System.Drawing.Color cl = Color.FromArgb(255,0,0); ...