Longlistselector элементы не добавлены правильно в группах - PullRequest
0 голосов
/ 05 декабря 2011

Я пытаюсь построить LongListSelector (инструментарий), используя ObservableCollection.Я следовал этому учебнику, и все отлично работает с примерами данных.Однако, как только я пытаюсь заполнить список данными, загруженными из Интернета, это становится беспорядком!Есть пустые группы, элементы размещены неправильно, и несколько вещей отсортированы по алфавиту.

Я использую этот код для создания пустых групп для всех букв:

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, который загружает 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" вместо "м".Кроме того, «f» должно быть перед «g»: иногда группы сортируются правильно (например, «Австрия» не первая в файле xml, но она отображается вверху списка, где она должна быть!) Ииногда нет («Италия» - одна из первых стран, перечисленных в файле, но в списке она стоит после «и»!) ...

Есть идеи?

В любом случае, спасибо.

Ответы [ 2 ]

1 голос
/ 15 декабря 2011

Вы пытались использовать другой подход к группировке? Набор инструментов 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
    }
0 голосов
/ 18 января 2012

Мне так понравилось:

  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);}
    }
}
...