向列表添加索引以显示列表中从1到最大项目的排名

时间:2015-03-12 20:04:00

标签: c# linq xaml

我正在使用MVVM Light。我必须将结果列表绑定到我的XAML页面。我用XML文件中的项目填充列表。这些项目没有id或索引。

但是,我想在索引列表框中添加索引号。

public async Task<List<MyClass>> getItemsList()
{
    var temp = await _IDataService.GetItems();
    List<MyClass> tempItemsList = new List<MyClass>();

    tempItemsList = (from Item in temp
                          orderby Item.Name descending
                          select Item).ToList();

    return tempItemsList;
}

在XAML页面上,我使用以下代码:

 <ListBox Grid.Row="1"
                 ItemsSource="{Binding ItemsList}"
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                 ScrollViewer.VerticalScrollBarVisibility="Visible"
                 Margin="18,0,0,18">

然后我可以像这样读出该列表中的属性:

 <TextBlock Text="{Binding Name}" />

但在此之前,我想放置一个索引,例如:

<TextBlock Text="{Binding ItemsList.Index}" />

知道如何添加这样的索引吗?

2 个答案:

答案 0 :(得分:0)

***该示例使用从零开始的索引。

示例数据模型:

public class StudentList
{
    public List<Student> Students { get; set; }

    public StudentList()
    {
        Students = new List<Student>
        {
            new Student {Name = "Student 1"},
            new Student {Name = "Student 2"},
            new Student {Name = "Student 3"}
        };
    }
}

public class Student
{
    public string Name { get; set; }
}

转换器:

public class ListBoxItemIndexConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var dependencyObject = value as DependencyObject;
        var item = FindFirstParentOfType<ListBoxItem>(dependencyObject);

        if (item == null)
            return null;

        var listBox = (ListBox) ItemsControl.ItemsControlFromItemContainer(item);
        if (listBox == null)
            return null;

        return listBox.ItemContainerGenerator.IndexFromContainer(item);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }

    private static T FindFirstParentOfType<T>(DependencyObject dependencyObject) 
        where T : DependencyObject
    {
        while (true)
        {
            if (dependencyObject == null)
                return null;

            var parent = VisualTreeHelper.GetParent(dependencyObject);

            var findFirstParentOfType = (parent as T);

            if (findFirstParentOfType != null)
                return findFirstParentOfType;

            dependencyObject = parent;
        }
    }
}

观点。

<Page
x:Class="WinPhoneStack.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinPhoneStack"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.DataContext>
    <!--sample data context-->
    <local:StudentList/>
</Page.DataContext>

<Page.Resources>
    <local:ListBoxItemIndexConverter x:Key="ListBoxItemIndexConverter1" />
</Page.Resources>

<Grid>
    <ListBox 
        ItemsSource="{Binding Students,Mode=OneTime}"
        ScrollViewer.HorizontalScrollBarVisibility="Disabled"
        ScrollViewer.VerticalScrollBarVisibility="Visible"
        Margin="18,0,0,18">

        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ListBoxItemIndexConverter1}, Mode=OneTime}" />
                    <TextBlock Text="{Binding Name,Mode=OneTime}" Margin="10 0"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

我希望它有所帮助。

答案 1 :(得分:0)

我相信您可以通过返回“MyClass”对象列表来实现所需的功能,这些对象包含一个包含索引值的自定义对象列表以及原始对象所需的数据(在下面的示例中为了简单起见,我将返回Tuple<int, string>个对象的列表:

public async Task<List<Tuple<int, string>>> getItemsList()
{
    var temp = await _IDataService.GetItems();
    List<MyClass> tempItemsList = new List<MyClass>();

    tempItemsList = (from Item in temp
                          orderby Item.Name descending
                          select Item).ToList();

    List<Tuple<int, string>> items = tempItemsList.Select((item, index) => new Tuple<int, string>(index + 1, item.Name));

    return items;
}

然后您可以将值绑定到相应的TextBlocks:

<TextBlock Text="{Binding Item1}" /> // Index
<TextBlock Text="{Binding Item2}" /> // Name