IT分享网

搜索
热搜: 活动 交友 discuz
查看: 761|回复: 0

[知识点] wpf – ListView交替背景色

[复制链接]
发表于 2017-1-25 14:16:17 | 显示全部楼层 |阅读模式
Wpf – Alternate background color of ListView.
Topic: Wpf – Alternate background color of ListView.
标题: wpf – ListView交替背景色
总的来说有三种变换背景色的方法,他们是
·         定义一个IValueConverter的Style
·         扩展ListView ,重载PrepareContainerOverride方法
·         使用 StyleSelector
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
首先看一看ValueConverter,代码如下:
First we need to introduce the ValueConverter, the code as below.
CSharp 代码,双击复制代码
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.
CSharp 代码,双击复制代码
        <namespc:BackgroundConverter xmlns:namespc="clr-namespace:AlternativeBackgroundListView.Converters" x:Key="myConverter" />
        <Style x:Key="myItemStyle" TargetType="{x:Type  ListViewItem}">
            <Setter Property="Background">
                <Setter.Value>
                    <Binding RelativeSource="{RelativeSource Self}"
                                     Converter="{StaticResource myConverter}" />
                </Setter.Value>
            </Setter>
        </Style>
在ListView上使用该style
And you will need to apply that style on the ListView.
CSharp 代码,双击复制代码
      <!-- Set Style on the IemContainer style
        The key is the "ItemContainerStyle -->
        <ListView x:Name="ListView"
                  ItemsSource="{Binding Customers}"
                  ItemContainerStyle="{StaticResource myItemStyle}"
                  Grid.Row="0"
                  >
            <ListView.Resources>
              
            </ListView.Resources>
            <ListView.View>
            <GridView
                AllowsColumnReorder="True"
                ColumnHeaderToolTip="Some Tooltip"
                >
                <GridViewColumn Header="Name"
                                DisplayMemberBinding="{Binding Name}"
                                Width="Auto"
                                ></GridViewColumn>
                    <GridViewColumn Header="Age"
                                DisplayMemberBinding="{Binding Age}"
                                Width="Auto"
                                ></GridViewColumn>
                    <GridViewColumn Header="Address"
                                DisplayMemberBinding="{Binding Address}"
                                Width="Auto"
                                >
                       
                       
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
 
扩展一个ListView
Derive a new class from ListView to alternate the background of a color.
首先看以下SubListView 类
We first introduce the sub listview that we wrote.
CSharp 代码,双击复制代码
    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.
CSharp 代码,双击复制代码
        <!-- the PrepareContainerForItemOverride is the key to the SubListView -->
        <namespc:SubListView xmlns:namespc="clr-namespace:AlternativeBackgroundListView.Controls"
                             x:Name="SubListView"
                             ItemsSource="{Binding Customers}"
                             Grid.Row="1"
                             >
            <namespc:SubListView.View>
                <GridView
                AllowsColumnReorder="True"
                ColumnHeaderToolTip="Some Tooltip"
                >
                    <GridViewColumn Header="Name"
                                DisplayMemberBinding="{Binding Name}"
                                Width="Auto"
                                ></GridViewColumn>
                    <GridViewColumn Header="Age"
                                DisplayMemberBinding="{Binding Age}"
                                Width="Auto"
                                ></GridViewColumn>
                    <GridViewColumn Header="Address"
                                DisplayMemberBinding="{Binding Address}"
                                Width="Auto"
                                >
                    </GridViewColumn>
                </GridView>
            </namespc:SubListView.View>
        </namespc:SubListView>
 
使用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
CSharp 代码,双击复制代码
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
CSharp 代码,双击复制代码
       <!-- THe key is ItemContainerStyleSelector -->
        <ListView x:Name="ListViewWithStyleSelector"
                  ItemsSource="{Binding Customers}"
                  Grid.Row="2"
                  ItemContainerStyleSelector="{DynamicResource myStyleSelector}"
                  >
            <ListView.Resources>
 
            </ListView.Resources>
            <ListView.View>
                <GridView
                AllowsColumnReorder="True"
                ColumnHeaderToolTip="Some Tooltip"
                >
                    <GridViewColumn Header="Name"
                                DisplayMemberBinding="{Binding Name}"
                                Width="Auto"
                                ></GridViewColumn>
                    <GridViewColumn Header="Age"
                                DisplayMemberBinding="{Binding Age}"
                                Width="Auto"
                                ></GridViewColumn>
                    <GridViewColumn Header="Address"
                                DisplayMemberBinding="{Binding Address}"
                                Width="Auto"
                                >
 
 
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
数据和DataContext
Data and DataContex
CSharp 代码,双击复制代码
    public class Customer
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
 
    }
 
CSharp 代码,双击复制代码
    public class MainWindowViewModel
    {
        #region Fields
 
        private List<Customer> _customers;
        #endregion Fields
 
 
        #region Contructors
        public MainWindowViewModel()
        {
            Initialize();
        }
        #endregion Constructors
 
        #region Methods
        public void Initialize()
        {
            _customers = new List<Customer>()
                             {
                                 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); }
        }
 

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2019-10-19 07:23 , Processed in 1.859327 second(s), 33 queries .

  

QQ|Archiver|手机版|小黑屋|IT分享网 ( 苏ICP备15049123号-2 )  

GMT+8, 2019-10-19 07:23 , Processed in 1.859327 second(s), 33 queries .

Powered by Discuz! X3.2 Designed by 999test.cn

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表