Как сделать автонумерацию пунктов в списке? - CodeHelper

Как сделать автонумерацию пунктов в списке?

2

Есть некоторый список с данными. Нужно отобразить его, добавив автонумерацию пунктов списка.

Лучший ответ:

1

Есть решение, но выглядит не очень красиво (источник приводить не буду, потому что это гнусный проприетарный сайт). Для примера рассмотрим список из двух колонок, в первой — номер строки, во второй — текст:

<ListBox ItemsSource="{Binding ItemsSourceField}" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="30" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock 
                    Grid.Row="0" 
                    Grid.Column="0" 
                    Text= "{Binding 
RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}, 
Converter={StaticResource rowIndexConverter}}"/>
                <TextBlock 
                    Grid.Row="0" 
                    Grid.Column="1" 
                    Text="{Binding Text}" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Код конвертера:

public class RowIndexConverter: IValueConverter
{
    public object Convert(
        object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        ListBoxItem item = value as ListBoxItem;
        ListBox view = ItemsControl.ItemsControlFromItemContainer(item) as ListBox;
        int index = view.ItemContainerGenerator.IndexFromContainer(item);
        return index.ToString();
    }

    public object ConvertBack(
        object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        throw new Exception(...);
    }
}

Если коллекция-источник для списка может изменяться, то после изменения нужно выполнить код для синхронизации:

ICollectionView view = 
    CollectionViewSource.GetDefaultView(ItemsSourceField)
    as ListCollectionView;
view.Refresh();

Есть еще один вариант — в статье Rownumber in Silverlight Datagrid or Listbox

Новые ответы


0

Да, я тоже нашел этот вариант и остановился на моменте обновления коллекции. Никак не мог придумать, как это сделать. Да и сейчас думаю, на какое событие ListBox повесить данное обновление. Как ни странно, ничего подобного у ListBox найти не могу.

Вообще, текстовое поле с номером строки будет обновляться, если будет обновляться то значение, на которое оно забайндено. В вышеприведенном примере оно забайндено на сам ListBoxItem, а уж конвертер преобразует ListBoxItem в его порядковый номер в ListBox. Пока не изменится ListBoxItem, номер не изменится.

Вот и возникла идея забайндить текстовое поле на количество строк в списке. При изменении списка количество строк изменяется, соответственно будет обновляться и значение в текстовом поле. Но тут несложно заметить некоторую неувязку - что мы получим в текстовом поле? Правильно, кол-во элементов в списке, что нам в общем-то не нужно. Однако проблема обновления решится. В конечном счете то, что будет отражено в текстовом поле, возвращает конвертер. В данном случае на вход ему подалось бы число элементов в списке, что не несет для нас никакой пользы. Однако тут есть еще одна лазейка - конвертору на вход можно подавать еще и дополнительный параметр. Синтаксис будет следующий:

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType=ListBox}, Path=Items.Count, Converter={StaticResource myConverterKey}, 
ConverterParameter=и_вот_тут_вопрос}"/>

Непонятно, как туда подать ListBoxItem. На сколько я понял, байндинг внутри байндинга использовать нельзя.


v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.