日期:2014-05-16  浏览次数:20736 次

WindowsPhone中ListBox奇偶行交差背景色实现

当然,是不依赖于数据源的。

先上个最终效果图给大家看一下。。。

 

方法一 依赖于数据源与ItemTemplate,放弃

第一个想到的时在数据源上指定一些数值,或直接加个Color字段让前台XAML中的ItemTemplate前台绑定。

但瞬间被否定,

这么样做的话每个次这个场景数据源都得改,ItemTemplate也得改,没有任何可重用性。

 用此方法简直2到无极限,虽然实现起来挺简单,可真的不敢写出那样的丢人代码.....

 

方法二  重载ListBox

 

核心思想:在绑定显示每行的时候,拿当前行的数据与数据源求index,判断奇偶数,然后设置颜色

 

由于做过多年的Web编程,想到Web中GirdView在绑定每一条数据的时候都会激发RowDataBound事件,想到ListBox应该与也有这种绑定单条数据的事件吧!

然后我找啊找,找啊找....

在此先说明一下ListBox类继承关系

ItemsControl,ISupportInitialize=>Selector=>ListBox

 

终于在ItemsControl类中中发现了PrepareContainerForItemOverride方法,当数据项需要在UI中渲染展现时,就会调用到它.

注意:并不是在绑定数据源,只是在UI展现时才会调用

 

PrepareContainerForItemOverride 的官方说明:准备指定元素以显示指定项

它有两个参数element与item,在这里element是ListBoxItem, item是你的数据项

 

先上代码

 

 public class ZListBox : ListBox
    {
        /// <summary>
        /// 奇行背景色
        /// </summary>
        SolidColorBrush OneColorBrush = new SolidColorBrush(Color.FromArgb(20, 255, 255, 255));
        /// <summary>
        /// 偶行背景色
        /// </summary>
        SolidColorBrush TwoColorBrush = new SolidColorBrush(Color.FromArgb(20, 0, 0, 0));

        /// <summary>
        /// 准备指定元素以显示指定项
        /// </summary>
        /// <param name="element">用于显示指定项的元素</param>
        /// <param name="item">要显示的项</param>
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            int index = 0;
            //返回一个循环访问集合的枚举器
            var enumerator = ItemsSource.GetEnumerator();
            //取得当前项的Index
            while (enumerator.MoveNext())
            {
                if (enumerator.Current == item)
                    break;
                index++;
            }

            ListBoxItem boxItem = element as ListBoxItem;
            boxItem.Background = Convert.ToBoolean(index % 2) ? OneColorBrush : TwoColorBrush;//判断奇偶数并设置背景
            base.PrepareContainerForItemOverride(element, item);
        }
    }

 

代码应该很简单,就不做更多的说明了。
但有一点需要注意,你若是ItemTemplate自己设置了背景色,在下这厢可就无能为力啦。。。

 

说一点题外的:

虚拟化与 PrepareContainerForItemOverride

虚拟化”是指一种技术,通过该技术,可根据屏幕上所显示的项来从大量数据项中生成 UI 元素的子集。

 PrepareContainerForItemOverride  只提取需要UI渲染的那部分据,比如我绑定了四十多条数据,它激发16次,因为它只准备显示UI相应的数据。在滚动列表时,才会进步一激发。

它可以取得你当前UI渲染了哪些数据,哪些内存中。