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.
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.
<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.
<!-- 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.
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.
<!-- 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
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
<!-- 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
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<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); } }
?
References:
How to : Alternate the Background Color for rows in a ListView.?http://msdn.microsoft.com/en-us/library/ms750769(v=vs.85).aspx
?