WPF: Связывание списков в XAML - как элемент может узнать свою позицию в списке? - PullRequest
7 голосов
/ 31 августа 2010

Учитывая следующий код XAML, который с поведением, похожим на ListControl:

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

Поскольку список может быть длинным (100-200 элементов), а элементы выглядят одинаково, я думаю, что было бы полезно для пользователя при прокрутке, если бы каждый элемент отображал свою позицию в списке. Как элемент в шаблоне может знать свою позицию в списке?

Ответы [ 3 ]

5 голосов
/ 31 августа 2010

Вот решение для взлома.Мы можем использовать Преобразование Значения с DataBinding.Итак, первый шаг - объявить наш 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
    }

Объявите, где вы хотите этот статический метод, чтобы получить родителя ListBox:

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));
        }

Затем в ListBox.Resources объявите наш конвертерследующим образом:

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

И наконец - 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>

Примечание: в этом примере элементы будут нумероваться начиная с 0 (ноль), выможете изменить его в методе Convert, добавив 1 к результату.

Надеюсь, это поможет ...

1 голос
/ 31 августа 2010

Согласно MSDN Magazine статья " Диаграммы с шаблонами данных ":

[...] DataTemplate потребуется доступ к индексу конкретного элемента данных в коллекции. Но достаточно просто включить эту информацию в бизнес-объект [...]

Таким образом, если не было изменений в .NET 4, не существует свойства «index of this item», если оно явно не включено в модель.

0 голосов
/ 31 августа 2010

Этот образец поддерживает сортировку:

Нумерованный список

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...