上文说到,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. kafka-manager 的编译和使用(附安装包)

    kafka-manager 的编译和使用(附安装包) 学习了:https://my.oschina.net/wangjiankui/blog/653139

  2. android:“新版飞机大战”源码开源啦!

    今天10.24,为了纪念程序猿的节日,把之前写过的一个"飞机大战"的一个源码开源了. 源码地址:https://github.com/nuptboyzhb/newplanegame ...

  3. 《Java设计模式》之接口模式

    -----------模式是思想的体现,而非详细的实现. 抽象的讲,类的接口是类同意其它类对象訪问的方法与字段集.接口通常代表一种承诺,即方法须要实现接口方法名表示的操作,遵循代码凝视和其它文档说明. ...

  4. C# .NET 如何批量增加或取消注释

    选中一批文本之后 批量增加注释:Ctrl+K Ctrl+C 批量取消注释:Ctrl+K Ctrl+U  

  5. Akka并发编程——第五节:Actor模型(四)

    本节主要内容: 1. 停止Actor 1. 停止Actor (1)通过ActorSystem.shutdown方法停止全部 Actor的执行 /* *停止Actor:ActorSystem.shutd ...

  6. HDU 3308 线段树单点更新+区间查找最长连续子序列

    LCIS                                                              Time Limit: 6000/2000 MS (Java/Oth ...

  7. cojs 1001. [WZOI2011 S3] 消息传递

    1001. [WZOI2011 S3] 消息传递 ★★   输入文件:messagew.in   输出文件:messagew.out   简单对比时间限制:1 s   内存限制:128 MB Prob ...

  8. 【OI】简单的分块

    介绍下简单的分块: 当我们遇到区间类问题的时候,如何保证我们快速而高效地完成操作? 答案是线段树分块. 所谓分块,就是把一个序列分成许多块分别维护.是不是想起了树状数组 这样能大大提高效率: 例如,我 ...

  9. linux常见基础问题

    1,32位与64位的区别,怎么查看系统版本? 32位相比于64位处理速度更慢一些,64位同样也比32位更占内存.用户体验上没有区别:用uname  -a 查看系统版本信息 2,swap分区的作用是什么 ...

  10. mysql自增主键在大量删除后如何重新设置避免断层

    alter table tt auto_increment=8; 表tt mysql> select * from tt; +----+ | id | +----+ | 1 | | 2 | | ...