【WP8】LoopingSelector

WP8的WindowsPhoneToolkit工具包中有一个 LoopingSelector

可以想选择日期或时间一样进行选择

【WP8】LoopingSelector

 

 

1、首先当然是引用WindowsPhoneToolkit

  在Nuget控制台:

 PM> Install-Package WPtoolkit

 

 

2、LoopingSelector 的数据源是 ILoopingSelectorDataSource类型的,我们先实现两个类继承该接口

【WP8】LoopingSelector
    public abstract class LoopingDataSourceBase : ILoopingSelectorDataSource

    {

        #region ILoopingSelectorDataSource Members



        public abstract object GetNext(object relativeTo);



        public abstract object GetPrevious(object relativeTo);



        private object _selectedItem;

        public object SelectedItem

        {

            get { return _selectedItem; }

            set

            {

                if (!Equals(_selectedItem, value))

                {

                    object previousSelectedItem = _selectedItem;

                    _selectedItem = value;



                    OnSelectionChanged(previousSelectedItem, _selectedItem);

                }

            }

        }



        public event EventHandler<SelectionChangedEventArgs> SelectionChanged;



        protected virtual void OnSelectionChanged(object oldSelectedItem, object newSelectedItem)

        {

            var handler = SelectionChanged;

            if (handler != null)

            {

                handler(this, new SelectionChangedEventArgs(new[] {oldSelectedItem}, new[] {newSelectedItem}));

            }

        }



        #endregion

    }
LoopingDataSourceBase 抽象类

 

【WP8】LoopingSelector
    public class ListLoopingDataSource<T> : LoopingDataSourceBase

    {

        private IComparer<T> comparer;

        private LinkedList<T> linkedList;

        private NodeComparer nodeComparer;

        private List<LinkedListNode<T>> sortedList;



        public IEnumerable<T> Items

        {

            get { return linkedList; }

            set

            {

                SetItemCollection(value);

            }

        }



        public IComparer<T> Comparer

        {

            get { return comparer; }

            set { comparer = value; }

        }



        private void SetItemCollection(IEnumerable<T> collection)

        {

            linkedList = new LinkedList<T>(collection);



            sortedList = new List<LinkedListNode<T>>(linkedList.Count);



            LinkedListNode<T> currentNode = linkedList.First;

            while (currentNode != null)

            {

                sortedList.Add(currentNode);

                currentNode = currentNode.Next;

            }



            IComparer<T> comparer = this.comparer;

            if (comparer == null)

            {

                if (typeof (IComparable<T>).IsAssignableFrom(typeof (T)))

                {

                    comparer = Comparer<T>.Default;

                }

                else

                {

                    throw new InvalidOperationException(

                        "There is no default comparer for this type of item. You must set one.");

                }

            }



            nodeComparer = new NodeComparer(comparer);

            sortedList.Sort(nodeComparer);

        }



        public override object GetNext(object relativeTo)

        {

            int index = sortedList.BinarySearch(new LinkedListNode<T>((T) relativeTo), nodeComparer);

            if (index < 0)

            {

                return default(T);

            }





            LinkedListNode<T> node = sortedList[index].Next;

            if (node == null)

            {

                node = linkedList.First;

            }

            return node.Value;

        }



        public override object GetPrevious(object relativeTo)

        {

            int index = sortedList.BinarySearch(new LinkedListNode<T>((T) relativeTo), nodeComparer);

            if (index < 0)

            {

                return default(T);

            }

            LinkedListNode<T> node = sortedList[index].Previous;

            if (node == null)

            {

                node = linkedList.Last;

            }

            return node.Value;

        }



        private class NodeComparer : IComparer<LinkedListNode<T>>

        {

            private readonly IComparer<T> comparer;



            public NodeComparer(IComparer<T> comparer)

            {

                this.comparer = comparer;

            }



            #region IComparer<LinkedListNode<T>> Members



            public int Compare(LinkedListNode<T> x, LinkedListNode<T> y)

            {

                return comparer.Compare(x.Value, y.Value);

            }



            #endregion

        }

    }
ListLoopingDataSource

  注意,数据源如果是对象,必须实现IComparer<T>接口,否则会抛出异常,当然,也可以重写ListLoopingDataSource类

下面是数据源对象,我们这里定义为Person

【WP8】LoopingSelector
    public class Person : IComparable<Person>

    {

        public string Name { get; set; }

        public int Age { get; set; }

        

        public int CompareTo(Person other)

        {

            //比较两个对象:这里只比较名字

            return String.CompareOrdinal(Name, other.Name);

        }

    }
Person

 

3、接下来是数据绑定

            <toolkitPrimitives:LoopingSelector

                x:Name="LoopingSelector"

                    DataSource="{Binding Items}"

                    ItemMargin="2,3,3,2"

                    ItemSize="200,150" 

                    FontSize="33" >

                <toolkitPrimitives:LoopingSelector.ItemTemplate>

                    <DataTemplate>

                        <Grid>

                            <StackPanel>

                                <TextBlock Text="{Binding Name}"></TextBlock>

                                <TextBlock Text="{Binding Age}"></TextBlock>

                            </StackPanel>

                        </Grid>

                    </DataTemplate>

                </toolkitPrimitives:LoopingSelector.ItemTemplate>

            </toolkitPrimitives:LoopingSelector>

 

【WP8】LoopingSelector
    public partial class LoopSelectorPage : INotifyPropertyChanged

    {

        #region Items



        /// <summary>

        /// The <see cref="Items" /> property's name.

        /// </summary>

        public const string ItemsPropertyName = "Items";



        private ListLoopingDataSource<Person> _items;



        /// <summary>

        /// 用于绑定到LoopingSelector的数据源对象

        /// </summary>

        public ListLoopingDataSource<Person> Items

        {

            get

            {

                return _items;

            }



            set

            {

                if (_items == value)

                {

                    return;

                }



                _items = value;

                RaisePropertyChanged(ItemsPropertyName);

            }

        }



        #endregion



        public LoopSelectorPage()

        {

            InitializeComponent();

            LoadApplicationBar();

            LoadData();

        }



        private void LoadApplicationBar()

        {

            ApplicationBar = new ApplicationBar();



            var appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative))

            {

                Text = "test"

            };

            appBarButton.Click += appBarButton_Click;

            ApplicationBar.Buttons.Add(appBarButton);





        }



        private void appBarButton_Click(object sender, EventArgs e)

        {

            //改变数据源

            Items = new ListLoopingDataSource<Person>

            {

                Items = new ObservableCollection<Person>

                {

                    new Person{Name = "Cnblogs", Age = 12},

                    new Person{Name = "CodePlex", Age = 12},

                    new Person{Name = "CodeProject", Age = 15},

                    new Person{Name = "CSDN", Age = 15},

                    new Person{Name = "51CTO", Age = 15},

                },

            };

            //注意,如果改变了数据源,必须设置其SelectedItem属性

            Items.SelectedItem = Items.Items.First();

        }



        private void LoadData()

        {

            Items = new ListLoopingDataSource<Person>

            {

                Items = new ObservableCollection<Person>

                {

                    new Person{Name = "aaa", Age = 12},

                    new Person{Name = "bbb", Age = 12},

                    new Person{Name = "ccc", Age = 15},

                    new Person{Name = "ddd", Age = 15},

                    new Person{Name = "eee", Age = 15},

                },

            };



            //注意,如果改变了数据源,必须设置其SelectedItem属性

            Items.SelectedItem = Items.Items.First();



            //也可以监听选择改变的事件

            Items.SelectionChanged += Items_SelectionChanged;



        }



        void Items_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)

        {

            MessageBox.Show(string.Format("add:{0}", ((Person)e.AddedItems[0]).Name));

        }



        #region INotifyPropertyChanged Members



        public event PropertyChangedEventHandler PropertyChanged;



        protected void RaisePropertyChanged(string name)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(name));

            }

        }



        #endregion

    }
LoopSelectorPage.xaml.cs

好了,数据源的集合是用 IEnumerable<T>存放的,如果需要添加和删除该数据源,可以使用List<T>对象,或是ObservableCollection<T> 对象存储

你可能感兴趣的:(selector)