上文说到,WinRt中,我们不能在Style的Setter使用Binding.这个问题其实从SL5之前,一直都不可以。但是,为了使用强大的Binding,人们也一直想使用各种方法来达到Binding

从茫茫的Web里找一个有用的东西,本来是很简单的一件事,但是,MS最近几年,经常自我革新,革自己的命,经常今天可以用的技术,明天换个名字,少点东西,就出来让万千小白来试了。从WPF/SL/WinRT一样的Xaml却不一样的精彩。我们常常想,要是WinRT的Xmal也如WPF的那么强大就好了。但这也是只是想想而已。

言归正传

在SL时代,我们参看的一般是这一文章

The taming of the phone [New SetterValueBindingHelper sample demonstrates its usefulness on Windows Phone 7 (and Silverlight 4)]

在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间隔变色(二)的更多相关文章

  1. WinRT ListView间隔变色(一)

    我们知道,在WPF里,MSDN提供了三种方法 1.使用转换器Converter 2.继承ListView类,自己处理 3.使用StyleSelctor 到了WinRT的世界了 1. Winrt中Set ...

  2. 【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法

    原文网址:http://blog.csdn.net/harvic880925/article/details/40475367 前言:前一篇文章给大家展示了传统的Listview的写法,但有的时候我们 ...

  3. Android ListView 之 SimpleAdapter 二 (包含 item 中按钮监听)

    1    MainActivity.java package com.myadapter; import java.util.ArrayList; import java.util.HashMap; ...

  4. wpf listview 行变色

    <ListView x:Name="listView_Date" Grid.Row="3" BorderBrush="{x:Null}" ...

  5. ListView间隔设置颜色

    在Adapter的getView中 if (position % 2 == 0) holder.shoucangbt.setBackgroundColor( Color.rgb(246, 246, 2 ...

  6. Windows 8.1中WinRT的变化(二)——新增功能

    首先我们来看看现有控件中新增的功能: FlipView编程方式切换时支持平滑滚动: 在Windows8中,FlipView在用手触控翻页的时候是有动画效果的,但当我们使用键盘或代码编程翻页时,却没有这 ...

  7. UI控件之ListView

    一,一个简单的TextView列表 public class FirstActivity extends Activity { private String[] data = {"Apple ...

  8. 【实战】初识ListView及提高效率

    简介: ListView是手机上最常用的控件之一,几乎所有的程序都会用到,手机屏幕空间有限,当需要显示大量数据的时候,就需要借助ListView来实现,允许用户通过手指上下滑动的方式将屏幕外的数据滚动 ...

  9. (转)解决ScrollView嵌套ListView或者GridView导致只显示一行的方法

    即动态获取ListView和GridView的高度 一.对于ListView ListView listview= new ListView(this); setListViewHeightBased ...

随机推荐

  1. 连通分量模板:tarjan: 求割点 &amp;&amp; 桥 &amp;&amp; 缩点 &amp;&amp; 强连通分量 &amp;&amp; 双连通分量 &amp;&amp; LCA(近期公共祖先)

    PS:摘自一不知名的来自大神. 1.割点:若删掉某点后.原连通图分裂为多个子图.则称该点为割点. 2.割点集合:在一个无向连通图中,假设有一个顶点集合,删除这个顶点集合,以及这个集合中全部顶点相关联的 ...

  2. php &amp; 和 &amp;amp; (主要是url 问题)

    ini_set('arg_separator.output','&'); 也能够在php.ini 改动

  3. Mysql-SQL优化-统计某种类型的个数

    有时我们想统计某种类型有多少个,会用这个SQL. 全表扫描之余,还要filesort.耗时1.34秒. mysql> select country,count(*) from t1 group ...

  4. Highcharts数据表示(3)

    Highcharts数据表示(3) 採用对象数组的形式,能够明白节点上每一个项目的值.可是当节点较多时,会造成大量的冗余代码. 假设不写配置项名称,对象数组就能够简化二维数组.形式例如以下: data ...

  5. [办公自动化]PPT文件太大,如何压缩?

    如果你经常需要制作PPT,文件太大的确是个问题. 那么应该如何压缩呢? 以office 2007为例 第一.可以选中图片,然后双击,在弹出的菜单栏中,选择压缩图片. 然后选择选项, 有三种比例可选,建 ...

  6. 【bzoj4245】[ONTAK2015]OR-XOR

    利用前缀和选m个区间等价于选m个数 从最高位开始找,如果这一位至少有m个0,则可以为0,该位为1的后面就不可以选了. 还要注意,最后一个数如果该位为1,那么这一位必须为1,然后要从62开始枚举,而不是 ...

  7. Android源码的下载、编译与导入到Android Studio【转】

    本文转载自:http://wl9739.github.io/2016/05/09/Android%E6%BA%90%E7%A0%81%E7%9A%84%E4%B8%8B%E8%BD%BD%E3%80% ...

  8. Keepalived+lvs 搭建高可用负载均衡

    本站点停止更新,请访问:blog.coocap.com 不了解负载均衡高可用的童鞋,强烈建议先看keepalived+nginx高可用负载均衡: 传送门(求粉):http://www.cnblogs. ...

  9. 【LNOI 2014】 LCA

    [题目链接] 点击打开链接 [算法] 考虑求lca(x,y)的深度 我们可以将从根到x路径上的点都打上标记,然后,询问y到根上路径的权值和 那么,求sigma(depth(lca(i,z)))(l & ...

  10. 洛谷P1850 [noip2016]换教室——期望DP

    题目:https://www.luogu.org/problemnew/show/P1850 注释掉了一堆愚蠢,自己还是太嫩了... 首先要注意选或不选是取 min 而不是 /2 ,因为这里的选或不选 ...