diff options
Diffstat (limited to 'Xamarin.Forms.Controls/GalleryPages/GroupedListContactsGallery.cs')
-rw-r--r-- | Xamarin.Forms.Controls/GalleryPages/GroupedListContactsGallery.cs | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/Xamarin.Forms.Controls/GalleryPages/GroupedListContactsGallery.cs b/Xamarin.Forms.Controls/GalleryPages/GroupedListContactsGallery.cs new file mode 100644 index 00000000..1058b692 --- /dev/null +++ b/Xamarin.Forms.Controls/GalleryPages/GroupedListContactsGallery.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; + +namespace Xamarin.Forms.Controls +{ + [Preserve (AllMembers = true)] + public class GroupedListContactsGallery + : ContentPage + { + internal class Contact + { + public string FirstName + { + get; + set; + } + + public string LastName + { + get; + set; + } + + public string FullName + { + get { return FirstName + " " + LastName; } + } + + public string Title + { + get; + set; + } + } + + readonly ListView _list = new ListView { + ItemTemplate = new DataTemplate (() => { + Label name = new Label(); + name.SetBinding (Label.TextProperty, "FullName"); + + Label title = new Label { Font = Font.SystemFontOfSize (NamedSize.Micro) }; + title.SetBinding (Label.TextProperty, "Title"); + + return new ViewCell { View = new StackLayout { + Children = { + name, + title + } + } }; + }), + + GroupDisplayBinding = new Binding ("Key"), + GroupShortNameBinding = new Binding ("Key"), + IsGroupingEnabled = true + }; + + readonly List<Contact> _contacts = new List<Contact> { + new Contact { FirstName = "Jason", LastName = "Smith", Title = "Software Engineer" }, + new Contact { FirstName = "Eric", LastName = "Maupin", Title = "Software Engineer" }, + new Contact { FirstName = "Seth", LastName = "Rosetter", Title = "Software Engineer" }, + new Contact { FirstName = "Stephane", LastName = "Delcroix", Title = "Software Engineer" } + }; + + readonly Random _rand = new Random (42); + + [Preserve (AllMembers = true)] + internal class Group + : ObservableCollection<Contact> + { + public Group (string key) + { + Key = key; + } + + public string Key + { + get; + private set; + } + } + + bool _sortedByFirst = true; + ObservableCollection<Group> _sortedContacts; + + public GroupedListContactsGallery() + { + var addRandom = new Button { Text = "Random" }; + addRandom.Clicked += (sender, args) => { + Contact contact = GetRandomContact(); + _contacts.Add (contact); + + AddContact (_sortedContacts, contact); + }; + + var addRandomToExisting = new Button { Text = "Random Group" }; + addRandomToExisting.Clicked += (sender, args) => { + Contact contact; + do { + contact = GetRandomContact(); + } while (!_sortedContacts.Any (g => GetSortChar (g.First()) == GetSortChar (contact))); + + _contacts.Add (contact); + AddContact (_sortedContacts, contact); + }; + + var groupByFirst = new Button { Text = "First" }; + groupByFirst.Clicked += (sender, args) => { + _sortedByFirst = true; + + SetupContacts(); + _list.ItemsSource = _sortedContacts; + }; + + var groupByLast = new Button { Text = "Last" }; + groupByLast.Clicked += (sender, args) => { + _sortedByFirst = false; + + SetupContacts(); + _list.ItemsSource = _sortedContacts; + }; + + Content = new StackLayout { + Orientation = StackOrientation.Vertical, + Children = { + new StackLayout { + Orientation = StackOrientation.Vertical, + Children = { + new StackLayout { + Orientation = StackOrientation.Horizontal, + Children = { + new Label { Text = "Sort: " }, + groupByFirst, + groupByLast + } + }, + + new StackLayout { + Orientation = StackOrientation.Horizontal, + Children = { + addRandom, + addRandomToExisting, + } + } + }, + }, + + + _list + } + }; + + SetupContacts(); + _list.ItemsSource = _sortedContacts; + } + + const string Chars = "abcdefghijklmnopqrstuvwxyz"; + + void SetupContacts() + { + var coll = new ObservableCollection<Group>(); + foreach (var contact in _contacts) + AddContact (coll, contact); + + _sortedContacts = coll; + } + + void AddContact (ObservableCollection<Group> contactGroups, Contact contact) + { + char sortChar = GetSortChar (contact); + + var collection = contactGroups.FirstOrDefault (col => { + var c = col.First(); + return (GetSortChar (c) == sortChar); + }); + + if (collection == null) { + var ocontacts = new Group (GetSortChar (contact).ToString()) { contact }; + InsertBasedOnSort (contactGroups, ocontacts, c => GetSortChar (c.First())); + } else + InsertBasedOnSort (collection, contact, c => GetSortString (c)[0]); + } + + int IndexOf<T> (IEnumerable<T> elements, T element) + { + int i = 0; + foreach (T e in elements) { + if (Equals (e, element)) + return i; + + i++; + } + + return -1; + } + + void InsertBasedOnSort<T,TSort> (IList<T> items, T item, Func<T, TSort> sortBy) + { + List<T> newItems = new List<T> (items); + newItems.Add (item); + int index = IndexOf (newItems.OrderBy (sortBy), item); + items.Insert (index, item); + } + + char GetSortChar (Contact contact) + { + return GetSortString (contact)[0]; + } + + string GetSortString (Contact contact) + { + return (_sortedByFirst) ? contact.FirstName : contact.LastName; + } + + Contact GetRandomContact() + { + Contact contact = new Contact(); + + int firstLen = _rand.Next (3, 7); + + var builder = new StringBuilder (firstLen); + for (int i = 0; i < firstLen; i++) { + char c = Chars[_rand.Next (0, Chars.Length)]; + builder.Append ((i != 0) ? c : char.ToUpper (c)); + } + + contact.FirstName = builder.ToString(); + + int lastLen = _rand.Next (3, 7); + builder.Clear(); + for (int i = 0; i < lastLen; i++) { + char c = Chars[_rand.Next (0, Chars.Length)]; + builder.Append ((i != 0) ? c : char.ToUpper (c)); + } + + contact.LastName = builder.ToString(); + contact.Title = "Software Engineer"; + + return contact; + } + } +} |