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 ...
随机推荐
- owncloud
owncloud https://dl.iuscommunity.org/pub/ius/stable/CentOS/6/x86_64/ [root@n1 ~]# rpm -Uvh ius-relea ...
- 装机、做系统必备:秒懂MBR和GPT分区表
从Intel 6系列主板之后,就开始提供UEFI BIOS支持,正式支持GPT硬盘分区表,一举取代了此前的MBR分区表格式,不过为了保持对老平台的兼容,微软即使最新的Windows 10系统也继续提供 ...
- 笔记本电脑 联想 Thinkpad E420 无法打开摄像头怎么办
1 计算机管理-右击USB视频设备(应该显示为黄色问号,表示驱动安装不成功),点击浏览计算机以查找驱动程序软件 2 选择"从计算机的设备驱动程序列表中选择",然后选择Microso ...
- 神马都是浮云,unity中自己写Coroutine协程源代码
孙广东 2014.7.19 无意之间看到了,Unity维基上的一篇文章, 是关于自己写协程的介绍. 认为非常好,这样能更好的了解到协程的执行机制等特性.还是不错的. 原文链接地址例如以下: ht ...
- ajax请求同步与异步的区别
//同步请求 $.ajax({ type:'post', url:"<c:url value='/device/org/' />"+val, data:{'org ...
- 如何配置MYSQL的MASTER---SLAVE复制备份?
如何配置MYSQL的MASTER---SLAVE复制备份? 一.配置一个mysql服务器做master: 在配置文件my.ini中添加如下内容: log-bin=matster-binlog- ...
- go4--break,continue + 标签
package main /* 指针 Go虽然保留了指针,但与其它编程语言不同的是,在Go当中不 支持指针运算以及”->”运算符,而直接采用”.”选择符来操作指针 目标对象的成员 操作符”&am ...
- JTabbedPane的LookAndFeel--TabbedPaneUI
在定制JTabbedPane的时候是需要使用到LookAndFeel的,而使用LookAndFeel定制的时候,其实主要是继承BasicTabbedPaneUI. to be continue...
- oracle基本建表语句
oracle基本建表语句 2010-09-20 10:37:33| 分类: 数据库 | 标签:数据库 oracle |字号 订阅 --创建用户create user han identifie ...
- luogu 3958 奶酪
noip2017 D2T1 奶酪 某zz选手没有想到可以用并查集来做,直接用了dijskstra,结果被ccf老爷机卡成了70分 题目大意: 现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为 ...