zoukankan      html  css  js  c++  java
  • 【WP8】LoopingSelector

    WP8的WindowsPhoneToolkit工具包中有一个 LoopingSelector

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

    1、首先当然是引用WindowsPhoneToolkit

      在Nuget控制台:

     PM> Install-Package WPtoolkit

     

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

        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 抽象类
        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

        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>
        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> 对象存储

  • 相关阅读:
    Wakeari(有诡)念摄模式的渲染原理和帧率暴跌原因分析,及更优化的渲染方案设想
    离心力与木桶实验
    搬家成功!
    x264编码参数大测试:05 subme与crf(g)
    四探C#类与结构体究竟谁快——跨程序集(assembly)调用
    x264编码参数大测试:03 subme与crf(c)
    昨日购买了华为U8800+。晒联通2.2版系统与官方2.3版系统的评测跑分。
    用JavaScript生成Android SDK的下载地址(3)——放弃xsl,纯JavaScript转换xml为html
    向量除法——标量乘法的逆运算
    [Color]灰度系数与网点增大
  • 原文地址:https://www.cnblogs.com/bomo/p/3617298.html
Copyright © 2011-2022 走看看