Chinaunix首页 | 论坛 | 博客
  • 博客访问: 49392
  • 博文数量: 21
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 190
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-24 15:25
文章分类

全部博文(21)

文章存档

2013年(21)

我的朋友

分类: C#/.net

2013-07-02 18:55:28

Contents

Wpf – Alternate background color of ListView.

Topic: Wpf – Alternate background color of ListView.

标题: wpf – ListView交替背景色

总的来说有三种变换背景色的方法,他们是

·         定义一个IValueConverterStyle

·         扩展ListView ,重载PrepareContainerOverride方法

·         使用 StyleSelector

·         ItemsControl.AlternationIndex AlternationCount

In general there are three ways to alternate the background color of a ListView.

They are

·         Define a style that uses an IValueConverter to Alternate Background color

·         Derive a New class from ListView to Alternate Background color

·         Use a StyleSelector to Alternate Background color

·         ItemsControl.AlternationIndex and AlternationCount

 

首先看一看ValueConverter,代码如下:

First we need to introduce the ValueConverter, the code as below.

public sealed class BackgroundConverter : IValueConverter

    {

        #region IValueConverter

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            ListViewItem item = (ListViewItem) value;

            ListView listView = ItemsControl.ItemsControlFromItemContainer(item) as ListView; // Use the ItemsControl.ItemsContainerFromItemContainer(item) to get the ItemsControl.. and cast

 

            // Get the index of a ListViewItem

            int index = listView.ItemContainerGenerator.IndexFromContainer(item); // this is a state-of-art way to get the index of an Item from a ItemsControl

            if (index % 2 == 0)

                return Brushes.LightBlue;

            else

            {

                return Brushes.Beige;

            }

        }

 

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            throw new NotImplementedException();

        }

        #endregion IValueConverter

    }


它使用了ListView.ItemsControlFromItemContainer(item)拿到Item 的Container,然后, 调用ListView.ItemContainerGenerator.IndexFromContainer(item);得到Container的index;

这样使用该Style.

Basically, it uses the ListView.ItemsControlFromItemContainer(item) to get the container for an single Item, and then with the Container that it returns, it can get an index from the ListView – the method to call is  ListView.ItemContainerGenerator.IndexFromContainer(item);

You will need to apply the Style somewhere.

       

       


ListView上使用该style

And you will need to apply that style on the ListView.

     

       

                  ItemsSource="{Binding Customers}"

                  ItemContainerStyle="{StaticResource myItemStyle}"

                  Grid.Row="0"

                  >

           

              

           

           

           

                AllowsColumnReorder="True"

                ColumnHeaderToolTip="Some Tooltip"

                >

               

                                DisplayMemberBinding="{Binding Name}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Age}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Address}"

                                Width="Auto"

                                >

                       

                       

                   

               

           

       

 

扩展一个ListView

Derive a new class from ListView to alternate the background of a color.

首先看以下SubListView

We first introduce the sub listview that we wrote.

    public sealed class SubListView : ListView

    {

 

        protected override void PrepareContainerForItemOverride(System.Windows.DependencyObject element, object item)

        {

            base.PrepareContainerForItemOverride(element, item);

            if (View is GridView)

            {

                int index = ItemContainerGenerator.IndexFromContainer(element); // The ItemContainerGenerator has method to get index for a given Item

                ListViewItem lvi = element as ListViewItem;

                if (index%2 == 0)

                    lvi.Background = Brushes.LightBlue;

                else

                {

                    lvi.Background = Brushes.Beige;

                }

            }

        }

    }

 

关键在于ItemContainerGenerator.IndexFromContainer(哪里见过呢),要重载的方法是PreareContianerOverride().

The key here is the ItemContainerGenerator.IndexFromContainer (sounds familiar)?? And the method that we override is PreareContianerOverride()

使用SubListView, xaml如下

To use the SubListview, you can use this in the xaml file.

       

       

                             x:Name="SubListView"

                             ItemsSource="{Binding Customers}"

                             Grid.Row="1"

                             >

           

               

                AllowsColumnReorder="True"

                ColumnHeaderToolTip="Some Tooltip"

                >

                   

                                DisplayMemberBinding="{Binding Name}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Age}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Address}"

                                Width="Auto"

                                >

                   

               

           

       

 

使用Style selector

Use of a Style Selector

关键实在ListView. ItemContainerStyleSelector,首先看实现。

The use of style selector uses on the ListView’s ItemContainerStyleSelector. First let’s see the ListViewItemStyleSelector

public class ListViewItemStyleSelector : StyleSelector

    {

        public override System.Windows.Style SelectStyle(object item, System.Windows.DependencyObject container)

        {

            Style st = new Style();

            st.TargetType = typeof (ListViewItem);

            Setter backgroundSetter = new Setter();

            backgroundSetter.Property = ListViewItem.BackgroundProperty;

            ListView listView = ItemsControl.ItemsControlFromItemContainer(container) as ListView;

            int index = listView.ItemContainerGenerator.IndexFromContainer(container);

            if (index%2 == 0)

                backgroundSetter.Value = Brushes.LightBlue;

            else

            {

                backgroundSetter.Value = Brushes.Beige;

            }

            st.Setters.Add(backgroundSetter);

            return st;

        }

 

    }

使用Style selector,我们希望作到如下

To use the StyleSelector, here is what you do

      

       

                  ItemsSource="{Binding Customers}"

                  Grid.Row="2"

                  ItemContainerStyleSelector="{DynamicResource myStyleSelector}"

                  >

           

 

           

           

               

                AllowsColumnReorder="True"

                ColumnHeaderToolTip="Some Tooltip"

                >

                   

                                DisplayMemberBinding="{Binding Name}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Age}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Address}"

                                Width="Auto"

                                >

 

 

                   

               

           

       


数据和DataContext

Data and DataContex

    public class Customer

    {

        public string Name { get; set; }

        public int Age { get; set; }

        public string Address { get; set; }

 

    }

 

    public class MainWindowViewModel

    {

        #region Fields

 

        private List _customers;

        #endregion Fields

 

 

        #region Contructors

        public MainWindowViewModel()

        {

            Initialize();

        }

        #endregion Constructors

 

        #region Methods

        public void Initialize()

        {

            _customers = new List()

                             {

                                 new Customer()

                                     {

                                       Name  = "Joe",

                                       Address = "Hanhua",

                                       Age = 12,

                                     },

                                  new Customer()

                                     {

                                       Name  = "Nora",

                                       Address = "Hanhua",

                                       Age = 32,

                                     },

                                  new Customer()

                                     {

                                       Name  = "Karl",

                                       Address = "Huaihai",

                                       Age = 12,

                                     },

                                 new Customer()

                                     {

                                       Name  = "Summer",

                                       Address = "Huaihai",

                                       Age = 24,

                                     },

                             };

        }

        #endregion Methods

 

 

        public CollectionView Customers

        {

            get { return new CollectionView(_customers); }

        }

 

ItemsControl.AlternationIndex AlternationCount

ItemsControl.AlternationIndex and AlternationCount

但是, 做交替色的方法还远不只如此,比如说, 你可以使用ItemsControl.AlternationIndexs属性;使用ItemsControl.AlternationIndex时要确保和AlternationCount一同使用。

However, there are more means that you can do alternation.. For another, you can use the ItemsControl.AlternationIndex property; And together with the ItemsControl.AlternationIndex (or ListView.AlternationIndex or ListBox.AlternationIndex), you should as well use the AlternationCount..

首先,让我们看一下 style的定义

First, let’s check the Style definition.

AlternationConverter 是一个系统的内建converter.他接受一个index参数,返回它对应index的对象。

The AlternationConverter is a built-in converter, which takes a index parameter and gives out object based on the index that it has.

       

       

           

            CornflowerBlue

            LightBlue

       

 

       

            White

            Black

            Navy

       

 

       

为了应用在控件上,使用该style的时候一定要使用AlternationCount属性。

And apply the style on the ItemsControl, you have to make sure to use the AlternationCount property.

       

       

            AlternationCount="3"

            ItemsSource="{Binding Customers}"

            ItemContainerStyle="{StaticResource alternatingWithBinding}"

            Grid.Row="3"

            >

           

               

                AllowsColumnReorder="True"

                ColumnHeaderToolTip="Some Tooltip"

                >

                   

                                DisplayMemberBinding="{Binding Name}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Age}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Address}"

                                Width="Auto"

                                >

                   

               

          

       


除了使用converter和数据绑定,你也可以选择使用DataTrigger,下面是该修改后的style.

Beside the data binding style, you can as well use the DataTrigger based on the AlternationIndex, here is the style with data trigger.

       

       

同样的,你需要指定一个AlternationCount的值。

The same thing, you have to use the AlternationCount

       

       

            Grid.Row="4"

            ItemsSource="{Binding Customers}"

            ItemContainerStyle="{StaticResource alternatingWithTriggers}"

            AlternationCount="3"

            >

           

               

                    AllowsColumnReorder="True"

                    ColumnHeaderToolTip="Some tooltip">

                   

                                DisplayMemberBinding="{Binding Name}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Age}"

                                Width="Auto"

                                >

                   

                                DisplayMemberBinding="{Binding Address}"

                                Width="Auto"

                                >

                   

               

           

       

在其他的ItemsControl上,你可以采用同样的技术,比如说ListBox或者是DataGrid.

You can employ the same logic not only to the ListView, but as well other ItemsControl, such as the ListBox and DataGrid? E.g. is shown below.

      

            ItemsSource="{Binding Customers}"

            ItemContainerStyle="{StaticResource alternatingWithTriggers2}"

            AlternationCount="3"

            Grid.Row="4">

           

               

                    DataType="{x:Type local:Customer}"

                    xmlns:local="clr-namespace:AlternativeBackgroundListView.Models">

                   

                        >

                       

                           

                            

                           

                       

                       

                       

                       

                   

               

           

       


References:

.

:

 

Conclusion

Wpf – Alternate background color of ListView

References:

 

阅读(2974) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~