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交替背景色
总的来说有三种变换背景色的方法,他们是
·
定义一个IValueConverter的Style
·
扩展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
#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.
为了应用在控件上,使用该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: