wp图片滚动山寨方法:LoopingSelector

看见有人在微薄上讨论图片滚动的实现

水平有限搞不定,突然想起来SL ToolKits有个仿wp上日期、时间滚动的控件

定制下模版就比较形似图片滚动了

动手试试效果

 

 

首先找了120张WP壁纸,不过文件都比较小

image

 

然后新建工程,添加引用Microsoft.Phone.Controls.Toolkit.dll,添加图片,生成方式设为内容

参考Windows Phone Toolkit In Depth,使用LoopingSelector

首先创建类ListLoopingDataSource.cs

using System;
using System.Windows.Controls;
using Microsoft.Phone.Controls.Primitives;
namespace LoopingSelectorpic
{
    public abstract class LoopingDataSourceBase : ILoopingSelectorDataSource
    {
        private object selectedItem; 
 
10         #region ILoopingSelectorDataSource Members 
11  
12         public abstract object GetNext(object relativeTo); 
13  
14         public abstract object GetPrevious(object relativeTo); 
15  
16         public object SelectedItem 
17         { 
18             get 
19             { 
20                 return this.selectedItem; 
21             } 
22             set 
23             { 
24                 // this will use the Equals method if it is overridden for the data source item class 
25                 if (!object.Equals(this.selectedItem, value)) 
26                 { 
27                     // save the previously selected item so that we can use it  
28                     // to construct the event arguments for the SelectionChanged event 
29                     object previousSelectedItem = this.selectedItem; 
30                     this.selectedItem = value; 
31                     // fire the SelectionChanged event 
32                     this.OnSelectionChanged(previousSelectedItem, this.selectedItem); 
33                 } 
34             } 
35         }
36         public event EventHandler<SelectionChangedEventArgs> SelectionChanged; 
37  
38         protected virtual void OnSelectionChanged(object oldSelectedItem, object newSelectedItem) 
39         { 
40             EventHandler<SelectionChangedEventArgs> handler = 
41             this.SelectionChanged; 
42             if (handler != null) 
43             { 
44                 handler(this, new SelectionChangedEventArgs(new object[] { oldSelectedItem }, new object[] { newSelectedItem })); 
45             } 
46         } 
47  
48         #endregion 
49     }
50 }

 

然后创建类LoopingDataSourceBase.cs

1   using System;
2   using System.Collections.Generic;
3   using System.Collections;
4   namespace LoopingSelectorpic
5   {
6       public class ListLoopingDataSource<T> : LoopingDataSourceBase
7       {
8           private LinkedList<T> linkedList;
9           private List<LinkedListNode<T>> sortedList;
10          private IComparer<T> comparer;
11          private NodeComparer nodeComparer;
12 
13          public ListLoopingDataSource()
14          {
15          }
16 
17          public IEnumerable<T> Items
18          {
19              get
20              {
21                  return this.linkedList;
22              }
23              set
24              {
25                  this.SetItemCollection(value);
26              }
27          }
28 
29          private void SetItemCollection(IEnumerable<T> collection)
30          {
31              this.linkedList = new LinkedList<T>(collection);
32 
33              this.sortedList = new
34              List<LinkedListNode<T>>(this.linkedList.Count);
35              // initialize the linked list with items from the collections 
36              LinkedListNode<T> currentNode = this.linkedList.First;
37              while (currentNode != null)
38              {
39                  this.sortedList.Add(currentNode);
40                  currentNode = currentNode.Next;
41              }
42 
43              IComparer<T> comparer = this.comparer;
44              if (comparer == null)
45              {
46                  // if no comparer is set use the default one if available 
47                  if (typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
48                  {
49                      comparer = Comparer<T>.Default;
50                  }
51                  else
52                  {
53                      throw new InvalidOperationException("There is no default comparer for this type of item. You must set one.");
54                  }
55              }
56 
57              this.nodeComparer = new NodeComparer(comparer);
58              this.sortedList.Sort(this.nodeComparer);
59          }
60 
61          public IComparer<T> Comparer
62          {
63              get
64              {
65                  return this.comparer;
66              }
67              set
68              {
69                  this.comparer = value;
70              }
71          }
72 
73          public override object GetNext(object relativeTo)
74          {
75              // find the index of the node using binary search in the sorted list 
76              int index = this.sortedList.BinarySearch(new
77              LinkedListNode<T>((T)relativeTo), this.nodeComparer);
78              if (index < 0)
79              {
80                  return default(T);
81              }
82 
83              // get the actual node from the linked list using the index 
84              LinkedListNode<T> node = this.sortedList[index].Next;
85              if (node == null)
86              {
87                  // if there is no next node get the first one 
88                  node = this.linkedList.First;
89              }
90              return node.Value;
91          }
92 
93          public override object GetPrevious(object relativeTo)
94          {
95              int index = this.sortedList.BinarySearch(new
96              LinkedListNode<T>((T)relativeTo), this.nodeComparer);
97              if (index < 0)
98              {
99                  return default(T);
100             }
101             LinkedListNode<T> node = this.sortedList[index].Previous;
102             if (node == null)
103             {
104                 // if there is no previous node get the last one 
105                 node = this.linkedList.Last;
106             }
107             return node.Value;
108         }
109
110         private class NodeComparer : IComparer<LinkedListNode<T>>
111         {
112             private IComparer<T> comparer;
113
114             public NodeComparer(IComparer<T> comparer)
115             {
116                 this.comparer = comparer;
117             }
118
119             #region IComparer<LinkedListNode<T>> Members
120
121             public int Compare(LinkedListNode<T> x, LinkedListNode<T> y)
122             {
123                 return this.comparer.Compare(x.Value, y.Value);
124             }
125
126             #endregion
127         }
128
129     }
130 }

 

然后定义我们的数据类Picdata.cs

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
10 using System.Windows.Shapes;
11
12 namespace LoopingSelectorpic
13 {
14     public class Picdata : IComparable<Picdata>
15     {
16         public string Name
17         {
18             get;
19             set;
20         }
21
22         public string Url
23         {
24             get;
25             set;
26         }
27         public int ID
28         {
29             get;
30             set;
31         }
32
33         #region IComparable<Picdata> Members
34
35         public int CompareTo(Picdata other)
36         {
37             return this.ID.CompareTo(other.ID);
38         }
39
40         #endregion
41     }
42 }

 

然后在页面里添加LoopingSelector并定义模版(貌似工具箱里找不到,自己手打吧)

                <toolkit:LoopingSelector x:Name="LoopingSelector1" ItemMargin="5" ItemSize="400,530" HorizontalAlignment="Center" VerticalAlignment="Center" Width="400" Height="696" > 
                    <toolkit:LoopingSelector.ItemTemplate> 
                        <DataTemplate> 
                            <StackPanel> 
                                <StackPanel Width="400" Height="30">
                                    <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center"/>                   
                                </StackPanel>                                 
                                <Image Source="{Binding Url}" Stretch="Fill" Width="400" Height="500"/> 
                                <TextBlock Text="{Binding ID}"/> 
                            </StackPanel> 
                        </DataTemplate> 
                    </toolkit:LoopingSelector.ItemTemplate> 
                </toolkit:LoopingSelector>   

 

最后在page_load里填充数据并绑定

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            List<Picdata> data = new List<Picdata>();
            for (int i = 1; i <= 120; i++)
            {
                data.Add(new Picdata()
                {
                    Name = i.ToString() + ".jpg",
                    Url = new Uri("/pic/"+ i.ToString() +".jpg",UriKind.Relative).ToString(),
                    ID = i
                });
            }
            this.LoopingSelector1.DataSource = new ListLoopingDataSource<Picdata>()
            {
                Items = data,
                SelectedItem = data[2]
            };
        }

 

 

看下效果:

imageimage

 

 

后记:加载120张图片,模拟器还算流畅,不过真机滚动起来还是有明显的卡顿

估计图片少点的时候凑合能用吧,另外理论上旋转下可以横向滚动的,不过我旋转的貌似有点问题,总是位置不大合适,而且只有点击图片边缘部分才能滚动,望高手能指导下

 

源码:

posted @ 2012-04-26 16:57  sun8134  阅读(2221)  评论(2编辑  收藏  举报
分享按钮