windows phone開發學習–LoopingSelector

來源:互聯網
上載者:User

其實在上一篇自訂datetimepicker中已經提到了LoopingSelector,這是一個帶有滾動效果的控制項,要比list那種控制項美觀的多,使用者體驗也要好不少。微軟內建的控制項中是沒有這個控制項的,在silverlight中才有,下載最新的toolkit,然後引用

xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone.Controls.Toolkit"

就可以在xaml中添加loopingselector了

<toolkit:LoopingSelector Grid.Column="0" x:Name="selectorDouble" ItemMargin="2,3,3,2" ItemSize="100,100" FontSize="33"/>

不過很多時候,我發現loopingselector顯示的是簡單的整型數字,日期控制項中就是如此,顯然這是遠遠不夠的,我們應該能讓他顯示浮點型,字串類型,甚至還包括圖片,效果就像下面一樣

這些資料其實網上都有說,WP7 LoopingSelector in depth給出了詳細的實現過程,具體看這裡:http://windowsphonegeek.com/articles/WP7-LoopingSelector-in-depth--Part3-Advanced-data-binding

針對我目前所做的項目,我只需要顯示農曆中的月份和天數即可,參考了一下作者的源碼,發現實現很簡單,甚至不需要像之前自訂datetimepicker控制項那樣弄出兩個單獨的類,這些類本可以放在一起,甚至可以針對任意類型,所以實現浮點型還是字串,圖片等等不在話下。

最關鍵的是下面兩個函數,其他一切都好辦

// abstract the reusable code in a base class// this will allow us to concentrate on the specifics when implementing deriving looping data source classespublic abstract class LoopingDataSourceBase : ILoopingSelectorDataSource{private object selectedItem;#region ILoopingSelectorDataSource Memberspublic abstract object GetNext(object relativeTo);public abstract object GetPrevious(object relativeTo);public object SelectedItem{get{return this.selectedItem;}set{// this will use the Equals method if it is overridden for the data source item classif (!object.Equals(this.selectedItem, value)){// save the previously selected item so that we can use it // to construct the event arguments for the SelectionChanged eventobject previousSelectedItem = this.selectedItem;this.selectedItem = value;// fire the SelectionChanged eventthis.OnSelectionChanged(previousSelectedItem, this.selectedItem);}}}public event EventHandler<SelectionChangedEventArgs> SelectionChanged;protected virtual void OnSelectionChanged(object oldSelectedItem, object newSelectedItem){EventHandler<SelectionChangedEventArgs> handler = this.SelectionChanged;if (handler != null){handler(this, new SelectionChangedEventArgs(new object[] { oldSelectedItem }, new object[] { newSelectedItem }));}}#endregion}public class ListLoopingDataSource<T> : LoopingDataSourceBase{private LinkedList<T> linkedList;private List<LinkedListNode<T>> sortedList;private IComparer<T> comparer;private NodeComparer nodeComparer;public ListLoopingDataSource(){}public IEnumerable<T> Items{get{return this.linkedList;}set{this.SetItemCollection(value);}}private void SetItemCollection(IEnumerable<T> collection){this.linkedList = new LinkedList<T>(collection);this.sortedList = new List<LinkedListNode<T>>(this.linkedList.Count);// initialize the linked list with items from the collectionsLinkedListNode<T> currentNode = this.linkedList.First;while (currentNode != null){this.sortedList.Add(currentNode);currentNode = currentNode.Next;}IComparer<T> comparer = this.comparer;if (comparer == null){// if no comparer is set use the default one if availableif (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.");}}this.nodeComparer = new NodeComparer(comparer);this.sortedList.Sort(this.nodeComparer);}public IComparer<T> Comparer{get{return this.comparer;}set{this.comparer = value;}}public override object GetNext(object relativeTo){// find the index of the node using binary search in the sorted listint index = this.sortedList.BinarySearch(new LinkedListNode<T>((T)relativeTo), this.nodeComparer);if (index < 0){return default(T);}// get the actual node from the linked list using the indexLinkedListNode<T> node = this.sortedList[index].Next;if (node == null){// if there is no next node get the first onenode = this.linkedList.First;}return node.Value;}public override object GetPrevious(object relativeTo){int index = this.sortedList.BinarySearch(new LinkedListNode<T>((T)relativeTo), this.nodeComparer);if (index < 0){return default(T);}LinkedListNode<T> node = this.sortedList[index].Previous;if (node == null){// if there is no previous node get the last onenode = this.linkedList.Last;}return node.Value;}private class NodeComparer : IComparer<LinkedListNode<T>>{private IComparer<T> comparer;public NodeComparer(IComparer<T> comparer){this.comparer = comparer;}#region IComparer<LinkedListNode<T>> Memberspublic int Compare(LinkedListNode<T> x, LinkedListNode<T> y){return this.comparer.Compare(x.Value, y.Value);}#endregion}

然後我們就可以在頁面初始化的時候給loopingselector設定資料來源,然後綁定一下就OK,在作者的例子中給出了一次全部定義和每次添加一個的方法

public MainPage(){InitializeComponent();string[] cityNames = new string[] { "London", "New York", "Barcelona", "Madrid", "Berlin", "Bonn", "Munich", "Las Vegas" };this.selectorString.DataSource = new ListLoopingDataSource<string>() { Items = cityNames, SelectedItem = "Madrid" };List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };this.selectorInt.DataSource = new ListLoopingDataSource<int>() { Items = numbers, SelectedItem = 5 };List<DateTime> dates = new List<DateTime>();DateTime selectedDate = DateTime.Now;dates.Add(selectedDate);dates.Add(DateTime.Now.AddMonths(1));dates.Add(DateTime.Now.AddMonths(2));dates.Add(DateTime.Now.AddMonths(3));dates.Add(DateTime.Now.AddMonths(4));dates.Add(DateTime.Now.AddMonths(5));dates.Add(DateTime.Now.AddMonths(6));this.selectorDateTime.DataSource = new ListLoopingDataSource<DateTime>() { Items = dates, SelectedItem = selectedDate };List<double> doubleNumbers = new List<double> { 1.1, 2.15, 3.66, 4.457, 5.036, 6.7, 7.4, 8.54, 9.11 };this.selectorDouble.DataSource = new ListLoopingDataSource<double>() { Items = doubleNumbers, SelectedItem = 6.7 };}

最終實現的效果如下

其實我覺得不需要做成使用者控制項,乾脆做成頁面比較方便,toolkit中內建的datetimepicker其實都是一個頁面,與其做個控制項,然後再做個頁面上面放這個控制項,真不如一步到位實現。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.