使用LongListSelector
对日期进行分组的Windows Phone 8 SDK问题。
我熟悉grouping on letters的AlphaKeyGroup帮助方法。
是否有人为类似语言环境感知的日期做过/看过类似的写作? (数字也是一个加号)
答案 0 :(得分: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!
答案 1 :(得分:2)
在我和你现在被困在同一个例子后,我在this example from MSDN取得了成功。 Group.cs文件包含一个可以随字符串自由使用的组的实现。我的猜测是,您可以轻松添加DateTime的另一个属性,然后您可以尝试按日期分组。
答案 2 :(得分:1)
我使用AlphaKeyGroup的修改版本。这个新类我调用了StringKeyGroup,并根据项的第一个charachter创建组。所以这只是用StringKeyGroup替换AlphaKeyGroup的问题。
这个新功能可以像:
一样使用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;
}
}
}
答案 3 :(得分:0)
要将LongListSelector与数字一起使用,我们可以尝试按年龄对人员列表进行分组,而不是按名字的第一个字母(in the MSDN PeopleHub example)
进行分组他们使用神秘的AlphaKeyGroup,它是一个名字以相同字母开头的人的列表(该字母成为AlphaKeyGroup的Key)。 AlphaKeyGroups的人看起来像这样:
我们将使用IntegerKeyGroup,它是具有相同年龄的人员列表。 IntegerKeyGroups的人看起来像这样:
因此,要遵循GentryRiggen的框架,我们必须首先定义IntegerKeyGroup,然后将人们粘贴在他们所属的年龄组中。我把它们放在ViewModel文件中。
public class IntegerKeyGroup<T> : List<T>
{
public int Key { get; private set; }
public IntegerKeyGroup(int key)
{
Key = key;
}
}
注意IntegerKeyGroup只是一个List,但有一个名为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 example:
中的原始代码进行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>
这应该按整数分组,在这种情况下,年龄。