先展示一下控件效果:
这种效果做起来并不难,而且MSDN上已经有了一篇文章[1],谈到了如何设计一个每行背景色可变的ListView。但是众所周知WPF和Silverlight,尤其是Silverlight For WP7总是有点差距的,你会发现对于方法一,Silverlight不支持在Style中的Setter里面设置Binding,对于方法三,Silverlight不知道ItemContainerStyleSelector是神马玩意,看起来只有方法二能用,但是想实现“在Items集合改变后更新ListBox”的效果,文章最后的方法也不能用,因为CollectionViewSource的GetDefaultView方法在Silverlight里面也浮云了。
于是我们采用方法二,派生一个ListBox,然后想办法动态更新它。
一、派生一个ListBox的子类,并留出Color的接口:
public class PhasedColorListBox : ListBox
{
public SolidColorBrush Color1
{
get;
set;
}
public SolidColorBrush Color2
{
get;
set;
}
}
{
public SolidColorBrush Color1
{
get;
set;
}
public SolidColorBrush Color2
{
get;
set;
}
}
二、按照方法二,重写PrepareContainerForItemOverride方法:
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
int index = ItemContainerGenerator.IndexFromContainer(element);
// element实际上就是正要显示的ListBoxItem
ListBoxItem lvi = element as ListBoxItem;
if (index % 2 == 0)
{
lvi.Background = Color1;
}
else
{
lvi.Background = Color2;
}
}
{
base.PrepareContainerForItemOverride(element, item);
int index = ItemContainerGenerator.IndexFromContainer(element);
// element实际上就是正要显示的ListBoxItem
ListBoxItem lvi = element as ListBoxItem;
if (index % 2 == 0)
{
lvi.Background = Color1;
}
else
{
lvi.Background = Color2;
}
}
三、重写OnItemsChanged方法,实现动态更新:
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
for (int i = e.OldStartingIndex; i < Items.Count; i++)
{
ListBoxItem lvi = ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
if (i % 2 == 0)
{
lvi.Background = Color1;
}
else
{
lvi.Background = Color2;
}
}
}
}
{
base.OnItemsChanged(e);
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
for (int i = e.OldStartingIndex; i < Items.Count; i++)
{
ListBoxItem lvi = ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
if (i % 2 == 0)
{
lvi.Background = Color1;
}
else
{
lvi.Background = Color2;
}
}
}
}
至此大功告成,我们可以通过改变Color1和Color2来设置两种背景色,如果不设的话就是透明。如果以后想扩展为N色交替也很简单,小修改一下即可。
参考资料:
[1] 如何:改变 ListView 中各行的背景色
» 转载请注明来源及链接:未来代码研究所
No response