先展示一下控件效果:

这种效果做起来并不难,而且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;
    }
}

二、按照方法二,重写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;
    }
}

三、重写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;
            }
        }
    }
}

至此大功告成,我们可以通过改变Color1和Color2来设置两种背景色,如果不设的话就是透明。如果以后想扩展为N色交替也很简单,小修改一下即可。

参考资料:
[1] 如何:改变 ListView 中各行的背景色

» 转载请注明来源及链接:未来代码研究所

Related Posts:

One Response to “好玩的Windows Phone控件开发系列之一:Item背景颜色交替变化的ListBox”

Leave a Reply

World Line
Time Machine
Friendly Links
Online Tools