WPF:XAML中的绑定列表 - 项目如何知道其在列表中的位置?

use*_*890 7 data-binding wpf xaml list

给定以下具有ListControl行为的XAML代码:

    <StackPanel>
        <ItemsControl Name="_listbox" ItemsSource="{Binding ElementName=_userControl, Path=DataContext}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <DockPanel>
                         ...
                    </DockPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
Run Code Online (Sandbox Code Playgroud)

由于列表可以很长(100-200项),并且项目看起来相似,我认为如果每个项目都会在列表中显示它们的位置,那么在滚动期间对用户会有帮助.模板中的项目如何知道自己在列表中的位置?

Eug*_*rda 5

这是一个黑客解决方案.我们可以将Value Conversion与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
    }
Run Code Online (Sandbox Code Playgroud)

声明您想要此静态方法的任何位置以获取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));
        }
Run Code Online (Sandbox Code Playgroud)

然后在ListBox.Resources中声明我们的转换器如下:

<ListBox.Resources>
                <YourNamespace:ListItemToPositionConverter x:Key="listItemToPositionConverter"/>
            </ListBox.Resources>
Run Code Online (Sandbox Code Playgroud)

最后 - 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>
Run Code Online (Sandbox Code Playgroud)

注意:在此示例中,项目将从0(零)开始计算,您可以通过向结果添加1来在Convert方法中更改它.

希望这可以帮助...