3

Windows Phone 8 SDK 问题使用LongListSelector日期分组。我熟悉对字母进行分组的 AlphaKeyGroup 辅助方法。

有没有人做过/看过类似的类似语言环境的日期的文章?(数字也将是一个加号)

4

4 回答 4

6

所以我也有点挣扎,因为你提到的 MSDN 中的 AlphaKeyGroup 示例由于本地化而比它需要的更复杂。您要做的是创建一个新的 List 对象,该对象具有一个额外的属性,即 Key。此 Key 属性是您分组的名称。在 AlphaKeyGroup 示例中,它是您所在地区字母表中的每个字母。因此,创建您自己的继承自 List 的组对象。

public class TimeKeyGroup<T> : List<T>
{
    /// <summary>
    /// The Key of this group.
    /// </summary>
    public string Key { get; private set; }

    public TimeKeyGroup(string key)
    {
        Key = key;
    }
}

现在创建一个名为 CreateGroups 的方法,该方法接受您要分组的对象的 IEnumerable,并返回您刚刚创建的自定义列表对象的列表。在我的实现中,我将具有 TimeStamp 属性的 Workout 对象分组。在此方法中,为您想要的每种类型的组键名称创建组对象,例如“过去 7 天”或“过去 6 个月”。然后通过循环遍历传入的 IEnumerable 组并评估每个组以确定它们应该分组的位置来填充每个组。最后将每个分组列表添加到主组列表并返回。这是我的方法:

public static List<TimeKeyGroup<Workout>> CreateGroups(IEnumerable<Workout> workouts)
    {
        // Create List to hold each item
        List<TimeKeyGroup<Workout>> groupedWorkouts = new List<TimeKeyGroup<Workout>>();

        // Create a TimeKeyGroup for each group I want
        TimeKeyGroup<Workout> LastSeven = new TimeKeyGroup<Workout>("Last Seven Days");
        TimeKeyGroup<Workout> LastTwoWeeks = new TimeKeyGroup<Workout>("Last Two Weeks");
        TimeKeyGroup<Workout> LastMonth = new TimeKeyGroup<Workout>("Last Month");
        TimeKeyGroup<Workout> LastSixMonths = new TimeKeyGroup<Workout>("Last Six Months");
        TimeKeyGroup<Workout> LastYear = new TimeKeyGroup<Workout>("Last Year");
        TimeKeyGroup<Workout> AllTime = new TimeKeyGroup<Workout>("All Time");

        // Fill each list with the appropriate workouts
        foreach (Workout w in workouts)
        {
            if (w.TimeStamp > DateTime.Now.AddDays(-7))
            {
                LastSeven.Add(w);
                continue;
            }
            else if (w.TimeStamp > DateTime.Now.AddDays(-14))
            {
                LastTwoWeeks.Add(w);
                continue;
            }
            else if (w.TimeStamp > DateTime.Now.AddMonths(-1))
            {
                LastMonth.Add(w);
                continue;
            }
            else if (w.TimeStamp > DateTime.Now.AddMonths(-6))
            {
                LastSixMonths.Add(w);
                continue;
            }
            else if (w.TimeStamp > DateTime.Now.AddMonths(-12))
            {
                LastYear.Add(w);
                continue;
            }
            else
            {
                AllTime.Add(w);
            }
        }

        // Add each TimeKeyGroup to the overall list
        groupedWorkouts.Add(LastSeven);
        groupedWorkouts.Add(LastTwoWeeks);
        groupedWorkouts.Add(LastMonth);
        groupedWorkouts.Add(LastSixMonths);
        groupedWorkouts.Add(LastYear);
        groupedWorkouts.Add(AllTime);

        return groupedWorkouts;
    }

现在你有一个很好的分组列表列表。惊人的!剩下的只是将 LongListSelector 的 itemssource 属性连接到这个新列表并定义 JumpListStyle 和 GroupedHeaderTemplate。您引用的原始文章包含所有这些信息。

祝你好运,快乐的 Windows Phone 开发!

于 2013-07-21T16:46:20.370 回答
2

在我被困在与您现在相同的示例之后,我在MSDN的这个示例上取得了成功。Group.cs 文件包含一个组的实现,可以自由地与字符串一起使用。我的猜测是,您可以轻松添加 DateTime 的另一个属性,然后您可以尝试按日期分组。

于 2012-12-17T08:11:26.613 回答
1

好吧,我使用了 AlphaKeyGroup 的修改版本。我将这个新类称为 StringKeyGroup 并根据项目的第一个字符创建组。因此,只需将 AlphaKeyGroup 替换为 StringKeyGroup 即可。

这个新功能可以像这样使用:

myLonglistSelector.ItemSource = GroupedItems(myCollection);
....

public ObservableCollection<StringKeyGroup<myClass>> GroupedItems(IEnumerable<myClass> source)
    {
        return StringKeyGroup<myClass>.CreateGroups(source,
            System.Threading.Thread.CurrentThread.CurrentUICulture, 
            s => s.Name, true);
    }

这是 StringKeyGroup.cs 的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Globalization;

namespace MyNameSpace

{
public class StringKeyGroup<T> : ObservableCollection<T>
{
    public delegate string GetKeyDelegate(T item);
    public string Key { get; private set; }
    public StringKeyGroup(string key)
    {
        Key = key;
    }
    public static ObservableCollection<StringKeyGroup<T>> CreateGroups(IEnumerable<T> items, CultureInfo ci, GetKeyDelegate getKey, bool sort)
    {
        var list = new ObservableCollection<StringKeyGroup<T>>();

        foreach (var item in items)
        {
            var itemKey = getKey(item).Substring(0, 1).ToLower();

            var itemGroup = list.FirstOrDefault(li => li.Key == itemKey);
            var itemGroupIndex = itemGroup != null ? list.IndexOf(itemGroup) : -1 ;

            if (itemGroupIndex == -1)
            {
                list.Add(new StringKeyGroup<T>(itemKey));
                itemGroupIndex = list.Count - 1;
            }
            if (itemGroupIndex >= 0 && itemGroupIndex < list.Count)
            {
                list[itemGroupIndex].Add(item);
            }
        }

        if (sort)
        {
            foreach (var group in list)
            {
                group.ToList().Sort((c0, c1) => ci.CompareInfo.Compare(getKey(c0), getKey(c1)));
            }
        }

        return list;
    }
}
}  
于 2013-06-11T06:46:17.690 回答
0

要将 LongListSelector 与数字一起使用,让我们尝试按年龄分组人员列表,而不是按他们名字的第一个字母(在 MSDN PeopleHub 示例中

他们使用神秘的 AlphaKeyGroup,这是一个名字以相同字母开头的人的列表(该字母成为 AlphaKeyGroup 的键)。AlphaKeyGroups 的人可能如下所示:

  • Key = A:Amber、Amelia(其中两个 People 对象的名称都以 A 开头)
  • Key = B:Bob,Brian(其中两个 People 对象的名称都以 B 开头)
  • 键= C:等

我们将使用 IntegerKeyGroup,这是一个具有相同年龄的人的列表。IntegerKeyGroups 的人可能如下所示:

  • 键 = 23:Jennifer、Ryan(两个 People 对象都是 23 岁)
  • 键 = 26:Amber、Megan(两个 People 对象都是 26 岁)
  • 键 = 34:等

所以要遵循 GentryRiggen 的框架,我们必须首先定义 IntegerKeyGroup,然后将人们粘在他们所属的年龄组中。我把这些放在 ViewModel 文件中。

public class IntegerKeyGroup<T> : List<T>
{
    public int Key { get; private set; }

    public IntegerKeyGroup(int key)
    {
        Key = key;
    }
}

请注意,IntegerKeyGroup 只是一个 List,但具有一个称为 Key 的特殊整数成员。这意味着我们可以将年龄整数标记为 Key 的人员列表

现在我们需要将我们未排序的大列表排序为不同年龄的 IntegerKeyGroups,最后将所有这些 IntegerKeyGroups 组合在一起。这个IntegerKeyGroups 组合列表是 LongListSelector 接受显示的内容

public static List<IntegerKeyGroup<Person>> CreateGroups(IEnumerable<Person> UnsortedPeopleList)
{
    // Create combined list of IntegerKeyGroups
    List<IntegerKeyGroup<Person>> CombinedPeopleList = new List<IntegerKeyGroup<Person>>();

    // Create a IntegerKeyGroup for each age group I want,
    // The constructor parameters sets the Key to the IntegerKeyGroup
    IntegerKeyGroup<Person> Age23s = new IntegerKeyGroup<Person>(23);
    IntegerKeyGroup<Person> Age26s = new IntegerKeyGroup<Person>(26);
    IntegerKeyGroup<Person> Age34s = new IntegerKeyGroup<Person>(34);

    // Populate each IntegerKeyGroup with the appropriate Persons
    foreach (Person p in UnsortedPeopleList)
    {
        switch (p.Age)
        {
            case 23: Age23s.Add(p); continue;
            case 26: Age26s.Add(p); continue;
            case 34: Age34s.Add(p); continue;
            default: continue; // we don't support ages other than the 3 above 
        }
    }

    // Add each IntegerKeyGroup to the overall list
    CombinedPeopleList.Add(Age23s);
    CombinedPeopleList.Add(Age26s);
    CombinedPeopleList.Add(Age34s);

    return CombinedPeopleList;
}

仍然在 ViewModel 文件中,使用 CreateGroups 函数使 IntegerKeyGroups 列表可公开访问。

 public List<IntegerKeyGroup<Person>> AgeGroupedPeople
    {
        get
        {
            return CreateGroups(UnsortedPeople);
        }
    }

现在在 XAML 中,对MSDN PeopleHub 示例中的原始代码进行 1 处更改 :

<phone:LongListSelector Name="peopleLongListSelector"   
     ItemsSource="{Binding AgeGroupedPeople}" <!-- Change is in this line! -->
     JumpListStyle="{StaticResource LongListSelectorJumpListStyle}"  
     ListHeaderTemplate="{StaticResource LongListSelectorHeaderTemplate}"
     GroupHeaderTemplate="{StaticResource LongListSelectorGroupHeaderTemmplate}"
     ItemTemplate="{StaticResource LongListSelectorItemTemplate}"
     HideEmptyGroups ="true" IsGroupingEnabled ="true" LayoutMode="List">
 </phone:LongListSelector>

这应该按整数对人进行分组,在这种情况下是年龄。

于 2014-06-26T01:22:21.283 回答