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

时间:2010-08-31 08:38:34

标签: wpf data-binding list xaml

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

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

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

3 个答案:

答案 0 :(得分: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
    }

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

然后在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(零)开始计算,你可以在转换方法中通过向结果添加1来更改它。

希望这会有所帮助......

答案 1 :(得分:1)

根据MSDN Magazine文章“Charting with DataTemplates”:

  

[...] DataTemplate需要访问集合中特定数据项的索引。但是很容易将这些信息包含在业务对象[...]

因此,除非.NET 4中有更改,否则没有“此项的索引”属性,除非它明确包含在模型中。

答案 2 :(得分:0)

此示例支持排序:

Numbered listbox