longlistselector项目未在组中正确添加

时间:2011-12-04 21:38:35

标签: windows-phone-7 silverlight-toolkit longlistselector

我正在尝试使用ObservableCollection构建LongListSelector(工具包)。我遵循了this教程,一切都与样本数据一致。 但是,一旦我尝试使用从Internet下载的数据填充列表,它就变得一团糟!有空组,项目放置不正确,很少有东西按字母顺序排序。

我正在使用此代码为所有字母创建空组:

private static readonly string Groups = "#abcdefghijklmnopqrstuvwxyz";  

/* ... other things ... */ 

List<Country> empty = new List<Country>();  
foreach (char c in Groups)  
{  
    Group<Country> emptyGroup = new Group<Country>(c.ToString(), empty);  
    App.Colst.cityByCountryList.Add(emptyGroup);  
} 

然后我创建了一个WebClient,它从Internet下载xml文件并对其进行分析,以这种方式向组添加项目:

string id = dreader.GetAttribute("id");  
string name = dreader.GetAttribute("name_it");  
string citynumber = dreader.GetAttribute("citiesNumber");  

if (id != null && id != "")  
{  
    Group<Country> firstGroup = App.Colst.cityByCountryList[Groups.IndexOf(name.Substring(0, 1).ToLower())];  
    Country newCountry = new Country() { Lett = name.Substring(0, 1).ToLower(), Name = name };  
    firstGroup.Add(newCountry);  
} 

这是结果(我是新用户,我无法上传图片......所以我发布了链接):

Image

如您所见,组“f”已正确创建,但“Francia”应位于“f”而不是“m”。此外,“f”应该在“g”之前:有时组正确排序(例如“奥地利”不是xml文件中的第一个,但它显示在列表的顶部,它应该在哪里!)和有时候不是(“Italia”是文件中列出的第一批国家之一,但在列表中它是在“u”之后!)...

有什么想法吗?

非常感谢。

2 个答案:

答案 0 :(得分:1)

您是否尝试过使用不同的分组方法? silverlight工具包包含了一个很好的示例,展示了如何实现分组:

List movies = new List();
//Fill movie collection
 ...

var moviesByCategory = from movie in movies
                       group movie by movie.Category into c
                       orderby c.Key
                       select new PublicGrouping(c);
linqMovies.ItemsSource = moviesByCategory;

PublicGrouping 的位置是:

 /// 
    /// A class used to expose the Key property on a dynamically-created Linq grouping.
    /// The grouping will be generated as an internal class, so the Key property will not
    /// otherwise be available to databind.
    /// 
    /// The type of the key.
    /// The type of the items.
    public class PublicGrouping : IGrouping
    {
        private readonly IGrouping _internalGrouping;

        public PublicGrouping(IGrouping internalGrouping)
        {
            _internalGrouping = internalGrouping;
        }

        public override bool Equals(object obj)
        {
            PublicGrouping that = obj as PublicGrouping;

            return (that != null) && (this.Key.Equals(that.Key));
        }

        public override int GetHashCode()
        {
            return Key.GetHashCode();
        }

        #region IGrouping Members

        public TKey Key
        {
            get { return _internalGrouping.Key; }
        }

        #endregion

        #region IEnumerable Members

        public IEnumerator GetEnumerator()
        {
            return _internalGrouping.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _internalGrouping.GetEnumerator();
        }

        #endregion
    }

答案 1 :(得分:0)

我确实喜欢这个:

  ZoneDetails zones = new ZoneDetails();
AppUtility.CreateGroupedOC(zones);

 /// <summary>
    /// Groups a passed Contacts ObservableCollection
    /// </summary>
    /// <param name="InitialContactsList">Unordered collection of Contacts</param>
    /// <returns>Grouped Observable Collection of Contacts suitable for the LongListSelector</returns>
    public static ObservableCollection<GroupedOC<ZoneDetail>> CreateGroupedOC(ObservableCollection<ZoneDetail> InitialContactsList)
    {

        //Initialise the Grouped OC to populate and return
        ObservableCollection<GroupedOC<ZoneDetail>> GroupedContacts = new ObservableCollection<GroupedOC<ZoneDetail>>();

        //first sort our contacts collection into a temp List using LINQ
        var SortedList = (from con in InitialContactsList
                          orderby con.Name
                          select con).ToList();

        //Now enumerate throw the alphabet creating empty groups objects
        //This ensure that the whole alphabet exists even if we never populate them
        string Alpha = "#abcdefghijklmnopqrstuvwxyz";
        foreach (char c in Alpha)
        {
            //Create GroupedOC for given letter
            GroupedOC<ZoneDetail> thisGOC = new GroupedOC<ZoneDetail>(c.ToString());

            //Create a temp list with the appropriate Contacts that have this NameKey
            var SubsetOfCons = (from con in SortedList
                                where (string.Compare(con.Key, c.ToString(), StringComparison.OrdinalIgnoreCase) == 0)
                                select con).ToList<ZoneDetail>();

            //Populate the GroupedOC
            foreach (ZoneDetail csm in SubsetOfCons)
            {
                thisGOC.Add(csm);
            }

            //Add this GroupedOC to the observable collection that is being returned
            // and the LongListSelector can be bound to.
            GroupedContacts.Add(thisGOC);
        }
        return GroupedContacts;
    }

public class GroupedOC<T> : ObservableCollection<T>
{
    /// <summary>
    /// The Group Title
    /// </summary>
    public string Title
    {
        get;
        set;
    }

    /// <summary>
    /// Constructor ensure that a Group Title is included
    /// </summary>
    /// <param name="name">string to be used as the Group Title</param>
    public GroupedOC(string name)
    {
        this.Title = name;
    }

    /// <summary>
    /// Returns true if the group has a count more than zero
    /// </summary>
    public bool HasItems
    {
        get {return (Count != 0);}
    }
}