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
?