有时候我们可以希望在 ListBox 列表项前面加上序号,这样看起来更清楚,还可以配合使用快捷键等。
希望达到如下图的效果:
显然我们可以通过修改 ListBox 的模板来实现,只要在 Item 中加上数字这一项即可,利用 MultiBinding 和 IMultiValueConverter 即可实现。
示例
首先,我们创建一个 Person 类:
public class Person
{
public string Name { get; set; }
}
然后创建一个 Converter,继承自 IMultiValueConverter:
注意第 5~6 行,使用了 dynamic 类型,所以必须保证 list 有 IndexOf 这个扩展方法,IEnumerable<T> 是不行的。
public class IndexConverter : IMultiValueConverter
{
public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture)
{
dynamic item = values[0];
dynamic list = values[1];
return list.IndexOf(person) + 1;
}
public object[] ConvertBack( object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException ();
}
}
XAML 如下:
关键在于 17~20 行,分别绑定了单项数据和 ListBox 本身。
<Window x:Class="ListBoxIndex.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:listBoxIndex ="clr-namespace:ListBoxIndex"
Title="MainWindow" Height ="350" Width="525">
<Window.Resources>
<listBoxIndex: IndexConverter x:Key="IndexConverter"/>
</Window.Resources>
<StackPanel >
<Button Name="BtnDemo" Content="Add" Click="BtnDemo_OnClick"/>
<ListBox Name="LbxDemo">
<ListBox.ItemTemplate>
<DataTemplate DataType="listBoxIndex:Person">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}">
<TextBlock.DataContext>
<MultiBinding Converter="{StaticResource IndexConverter }">
<Binding/>
<Binding ElementName="LbxDemo" Path="ItemsSource"/>
</MultiBinding>
</TextBlock.DataContext>
</TextBlock>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel >
</Window>
代码如下:
namespace ListBoxIndex
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
readonly ObservableCollection <Person> _personList = new ObservableCollection <Person>();
public MainWindow()
{
InitializeComponent();
InitSource();
}
private void InitSource()
{
_personList.Add(new Person() {Name = "刘备" });
_personList.Add(new Person() {Name = "关羽" });
LbxDemo.ItemsSource = _personList;
}
private void BtnDemo_OnClick( object sender, RoutedEventArgs e)
{
_personList.Add(new Person() {Name = "张飞" });
LbxDemo.ItemsSource = _personList;
}
}
}