WPF: binding lists in XAML - how can an element know its position in the list?

Given the following XAML code, which is similar to ListControl behavior:

<StackPanel> <ItemsControl Name="_listbox" ItemsSource="{Binding ElementName=_userControl, Path=DataContext}"> <ItemsControl.ItemTemplate> <DataTemplate> <DockPanel> ... </DockPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> 

Since the list can be long (100-200 elements), and the elements look the same, I think it will be useful for the user during scrolling if each element displays its position in the list. How can an element in a template know its own position in the list?

+6
list data-binding wpf xaml
source share
3 answers

Here is a hacking solution. We can use Value Conversion with a DataBinding. So, the first step is to declare our ValueConvertor:

 public class ListItemToPositionConverter : IValueConverter { #region Implementation of IValueConverter public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var item = value as ListBoxItem; if (item != null) { var lb = FindAncestor<ListBox>(item); if (lb != null) { var index = lb.Items.IndexOf(item.Content); return index; } } return null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } #endregion } 

Declare wherever you want this static method to get the ListBox parent:

 public static T FindAncestor<T>(DependencyObject from) where T : class { if (from == null) return null; var candidate = from as T; return candidate ?? FindAncestor<T>(VisualTreeHelper.GetParent(from)); } 

Then in ListBox.Resources declares our converter as follows:

 <ListBox.Resources> <YourNamespace:ListItemToPositionConverter x:Key="listItemToPositionConverter"/> </ListBox.Resources> 

And finally - DataTemplate:

 <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Converter={StaticResource listItemToPositionConverter}}"/> <Label Content="{Binding Path=DisplayName}"></Label> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> 

Note: in this example, the elements will be listed starting from 0 (zero), you can change it in the Convert method by adding 1 to the result.

Hope this helps ...

+5
source share

According to the MSDN Journal Article Diagram with DataTemplates ":

[...] DataTemplate will need access to the index of a specific data item in the collection. But it’s easy enough to include this information in a business object [...]

So, if there were no changes in .NET 4, the property "index of this element" is absent if it is not explicitly included in the model.

0
source share

This example supports sorting:

Numbered List

0
source share

All Articles