PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/MVVMSidekick/MVVMSidekick.Shared/Collections.cs

https://github.com/zoujuny/MVVM-Sidekick
C# | 1039 lines | 684 code | 228 blank | 127 comment | 61 complexity | a3905258175e1472a075219e8693bf65 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.ComponentModel;
  6. using System.Linq.Expressions;
  7. using System.Runtime.Serialization;
  8. using System.Reflection;
  9. using System.Threading.Tasks;
  10. using System.Threading;
  11. using System.Windows.Input;
  12. using MVVMSidekick.ViewModels;
  13. using MVVMSidekick.Commands;
  14. using System.Runtime.CompilerServices;
  15. using MVVMSidekick.Reactive;
  16. using System.Reactive.Linq;
  17. using System.Reactive.Subjects;
  18. using System.Reactive;
  19. using MVVMSidekick.EventRouting;
  20. using System.Collections.ObjectModel;
  21. using System.Collections.Specialized;
  22. using System.IO;
  23. using System.Collections;
  24. #if NETFX_CORE
  25. using Windows.UI.Xaml;
  26. using Windows.UI.Xaml.Data;
  27. using Windows.UI.Xaml.Controls;
  28. using System.Collections.Concurrent;
  29. using Windows.UI.Xaml.Navigation;
  30. using Windows.UI.Xaml.Controls.Primitives;
  31. using Windows.Foundation.Collections;
  32. #elif WPF
  33. using System.Windows;
  34. using System.Windows.Controls;
  35. using System.Windows.Data;
  36. using System.Collections.Concurrent;
  37. using System.Windows.Navigation;
  38. using MVVMSidekick.Views;
  39. using System.Windows.Controls.Primitives;
  40. using MVVMSidekick.Utilities;
  41. #elif SILVERLIGHT_5||SILVERLIGHT_4
  42. using System.Windows;
  43. using System.Windows.Controls;
  44. using System.Windows.Data;
  45. using System.Windows.Navigation;
  46. using System.Windows.Controls.Primitives;
  47. #elif WINDOWS_PHONE_8||WINDOWS_PHONE_7
  48. using System.Windows;
  49. using System.Windows.Controls;
  50. using Microsoft.Phone.Controls;
  51. using System.Windows.Data;
  52. using System.Windows.Navigation;
  53. using System.Windows.Controls.Primitives;
  54. #endif
  55. namespace MVVMSidekick
  56. {
  57. namespace Collections
  58. {
  59. public class DependencyObservableCollection<T> : DependencyObject, ICollection<T>, IList<T>, INotifyCollectionChanged, INotifyPropertyChanged
  60. {
  61. protected ObservableCollection<T> _core = new ObservableCollection<T>();
  62. public DependencyObservableCollection()
  63. {
  64. var countBinding = new Binding();
  65. countBinding.Path = new PropertyPath("Count");
  66. countBinding.Mode = BindingMode.OneWay;
  67. countBinding.Source = _core;
  68. BindingOperations.SetBinding(this, CountProperty, countBinding);
  69. }
  70. public void Add(T item)
  71. {
  72. _core.Add(item);
  73. }
  74. public void Clear()
  75. {
  76. _core.Clear();
  77. }
  78. public bool Contains(T item)
  79. {
  80. return _core.Contains(item);
  81. }
  82. public void CopyTo(T[] array, int arrayIndex)
  83. {
  84. _core.CopyTo(array, arrayIndex);
  85. }
  86. public virtual int Count
  87. {
  88. get { return (int)GetValue(CountProperty); }
  89. protected set { SetValue(CountProperty, value); }
  90. }
  91. // Using a DependencyProperty as the backing store for Count. This enables animation, styling, binding, etc...
  92. public static readonly DependencyProperty CountProperty =
  93. DependencyProperty.Register("Count", typeof(int), typeof(DependencyObservableCollection<T>), new PropertyMetadata(0));
  94. public bool IsReadOnly
  95. {
  96. get { return false; }
  97. }
  98. public bool Remove(T item)
  99. {
  100. return _core.Remove(item);
  101. }
  102. public IEnumerator<T> GetEnumerator()
  103. {
  104. return _core.GetEnumerator();
  105. }
  106. IEnumerator IEnumerable.GetEnumerator()
  107. {
  108. return _core.GetEnumerator();
  109. }
  110. public event NotifyCollectionChangedEventHandler CollectionChanged
  111. {
  112. add { _core.CollectionChanged += value; }
  113. remove { _core.CollectionChanged -= value; }
  114. }
  115. public event PropertyChangedEventHandler PropertyChanged
  116. {
  117. add { ((INotifyPropertyChanged)_core).PropertyChanged += value; }
  118. remove { ((INotifyPropertyChanged)_core).PropertyChanged -= value; }
  119. }
  120. public int IndexOf(T item)
  121. {
  122. return _core.IndexOf(item);
  123. }
  124. public void Insert(int index, T item)
  125. {
  126. _core.Insert(index, item);
  127. }
  128. public void RemoveAt(int index)
  129. {
  130. _core.RemoveAt(index);
  131. }
  132. public T this[int index]
  133. {
  134. get
  135. {
  136. return _core[index];
  137. }
  138. set
  139. {
  140. _core[index] = value;
  141. }
  142. }
  143. }
  144. #if NETFX_CORE
  145. //public
  146. /// <summary>
  147. /// ObservableVector that raises events for IObservableCollection and IObservableVector
  148. /// </summary>
  149. /// <typeparam name="T"></typeparam>
  150. public class ObservableVector<T> : ObservableCollection<T>, Windows.Foundation.Collections.IObservableVector<object>
  151. {
  152. //// *** Constants ***
  153. //private const string PropertyNameCount = "Count";
  154. //private const string PropertyNameIndexer = "Item[]";
  155. //// *** Events ***
  156. //public event PropertyChangedEventHandler PropertyChanged;
  157. //public event NotifyCollectionChangedEventHandler CollectionChanged;
  158. // *** Constructors ***
  159. public ObservableVector()
  160. : base()
  161. {
  162. }
  163. public ObservableVector(IList<T> list)
  164. : base(list)
  165. {
  166. }
  167. // *** Protected Methods ***
  168. protected override void ClearItems()
  169. {
  170. base.ClearItems();
  171. //OnPropertyChanged(PropertyNameCount);
  172. //OnPropertyChanged(PropertyNameIndexer);
  173. //OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
  174. if (VectorChanged != null)
  175. {
  176. VectorChanged(this, new VectorChangedEventArgs { CollectionChange = Windows.Foundation.Collections.CollectionChange.Reset });
  177. }
  178. }
  179. protected override void InsertItem(int index, T item)
  180. {
  181. base.InsertItem(index, item);
  182. //OnPropertyChanged(PropertyNameCount);
  183. //OnPropertyChanged(PropertyNameIndexer);
  184. //OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
  185. if (VectorChanged != null)
  186. {
  187. VectorChanged(this, new VectorChangedEventArgs { CollectionChange = Windows.Foundation.Collections.CollectionChange.ItemInserted, Index = (uint)index });
  188. }
  189. }
  190. protected override void RemoveItem(int index)
  191. {
  192. T oldItem = base[index];
  193. base.RemoveItem(index);
  194. //OnPropertyChanged(PropertyNameCount);
  195. //OnPropertyChanged(PropertyNameIndexer);
  196. //OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldItem, index));
  197. if (VectorChanged != null)
  198. {
  199. VectorChanged(this, new VectorChangedEventArgs { CollectionChange = Windows.Foundation.Collections.CollectionChange.ItemRemoved, Index = (uint)index });
  200. }
  201. }
  202. protected override void SetItem(int index, T item)
  203. {
  204. T oldItem = base[index];
  205. base.SetItem(index, item);
  206. //OnPropertyChanged(PropertyNameIndexer);
  207. //OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem, index));
  208. if (VectorChanged != null)
  209. {
  210. VectorChanged(this, new VectorChangedEventArgs { CollectionChange = Windows.Foundation.Collections.CollectionChange.ItemChanged, Index = (uint)index });
  211. }
  212. }
  213. protected void OnPropertyChanged(string propertyName)
  214. {
  215. OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
  216. }
  217. // *** Event Handlers ***
  218. //protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
  219. //{
  220. // if (PropertyChanged != null)
  221. // PropertyChanged(this, e);
  222. //}
  223. //protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
  224. //{
  225. // if (CollectionChanged != null)
  226. // CollectionChanged(this, e);
  227. //}
  228. public event Windows.Foundation.Collections.VectorChangedEventHandler<object> VectorChanged;
  229. #region IList<object> Members
  230. int IList<object>.IndexOf(object item)
  231. {
  232. return IndexOf((T)item);
  233. }
  234. void IList<object>.Insert(int index, object item)
  235. {
  236. Insert(index, (T)item);
  237. }
  238. object IList<object>.this[int index]
  239. {
  240. get
  241. {
  242. return this[index];
  243. }
  244. set
  245. {
  246. this[index] = (T)value;
  247. }
  248. }
  249. #endregion
  250. #region ICollection<object> Members
  251. void ICollection<object>.Add(object item)
  252. {
  253. Add((T)item);
  254. }
  255. bool ICollection<object>.Contains(object item)
  256. {
  257. return Contains((T)item);
  258. }
  259. void ICollection<object>.CopyTo(object[] array, int arrayIndex)
  260. {
  261. for (int i = 0; i < Count; i++)
  262. {
  263. var idx = arrayIndex + i;
  264. array[idx] = this[i];
  265. }
  266. }
  267. bool ICollection<object>.Remove(object item)
  268. {
  269. return Remove((T)item);
  270. }
  271. #endregion
  272. #region IEnumerable<object> Members
  273. IEnumerator<object> IEnumerable<object>.GetEnumerator()
  274. {
  275. return this.OfType<Object>().GetEnumerator();
  276. }
  277. #endregion
  278. #region IEnumerable Members
  279. IEnumerator IEnumerable.GetEnumerator()
  280. {
  281. return this.GetEnumerator();
  282. }
  283. #endregion
  284. #region ICollection<object> Members
  285. public bool IsReadOnly
  286. {
  287. get { return false; }
  288. }
  289. #endregion
  290. }
  291. /// <summary>
  292. /// Provides data for the changed events of a vector
  293. ///// </summary>
  294. public class VectorChangedEventArgs : Windows.Foundation.Collections.IVectorChangedEventArgs
  295. {
  296. #region IVectorChangedEventArgs Members
  297. /// <summary>
  298. /// Describes the change that caused the change
  299. /// </summary>
  300. public Windows.Foundation.Collections.CollectionChange CollectionChange
  301. {
  302. get;
  303. set;
  304. }
  305. /// <summary>
  306. /// The index of the item changed
  307. /// </summary>
  308. public uint Index
  309. {
  310. get;
  311. set;
  312. }
  313. #endregion
  314. }
  315. #endif
  316. /// <summary>
  317. /// <para > The extension method for collections </para>
  318. /// <para>集合类型的扩展方法</para>
  319. /// </summary>
  320. public static class CollectionExtensions
  321. {
  322. /// <summary>
  323. /// <para>Transform to a dictionary with INotifyCollectionChanged</para>
  324. /// <para>生成一个带有集合变化通知的字典</para>
  325. /// </summary>
  326. /// <typeparam name="K"><para>Key Type</para><para>键类型</para></typeparam>
  327. /// <typeparam name="V"><para>Value Type</para><para>值类型</para></typeparam>
  328. /// <param name="items"><para>Source Dictionary</para><para>来源字典</para><para></para></param>
  329. /// <returns></returns>
  330. public static KeyedObserableCollection<K, V> ToKeyedObserableCollection<K, V>(this IDictionary<K, V> items)
  331. {
  332. return new KeyedObserableCollection<K, V>(items);
  333. }
  334. }
  335. public class KeyedObserableCollection<K, V> : ObservableCollection<KeyValuePair<K, V>>
  336. {
  337. public KeyedObserableCollection(IDictionary<K, V> items)
  338. {
  339. if (items == null)
  340. {
  341. throw new ArgumentException("items could not be null.");
  342. }
  343. var bak = items.ToList();
  344. _coreDictionary = items;
  345. items.Clear();
  346. foreach (var item in bak)
  347. {
  348. base.Add(item);
  349. }
  350. }
  351. IDictionary<K, V> _coreDictionary;
  352. int _coreVersion;
  353. int _shadowVersion;
  354. private void IncVer()
  355. {
  356. _coreVersion++;
  357. if (_coreVersion >= 1024 * 1024 * 1024)
  358. {
  359. _coreVersion = 0;
  360. }
  361. }
  362. protected override void ClearItems()
  363. {
  364. base.ClearItems();
  365. _coreDictionary.Clear();
  366. IncVer();
  367. }
  368. protected override void InsertItem(int index, KeyValuePair<K, V> item)
  369. {
  370. _coreDictionary.Add(item.Key, item.Value);
  371. base.InsertItem(index, item);
  372. IncVer();
  373. }
  374. protected override void SetItem(int index, KeyValuePair<K, V> item)
  375. {
  376. _coreDictionary.Add(item.Key, item.Value);
  377. RemoveFromDic(index);
  378. base.SetItem(index, item);
  379. IncVer();
  380. }
  381. private void RemoveFromDic(int index)
  382. {
  383. var rem = base[index];
  384. if (rem.Key != null)
  385. {
  386. _coreDictionary.Remove(rem.Key);
  387. }
  388. IncVer();
  389. }
  390. protected override void RemoveItem(int index)
  391. {
  392. RemoveFromDic(index);
  393. base.RemoveItem(index);
  394. IncVer();
  395. }
  396. #if SILVERLIGHT_5||NET40||WINDOWS_PHONE_7
  397. Dictionary<K, V> _shadowDictionary;
  398. public IDictionary<K, V> DictionaryItems
  399. {
  400. get
  401. {
  402. if (_shadowDictionary == null || _shadowVersion != _coreVersion)
  403. {
  404. _shadowDictionary = new Dictionary<K, V>(_coreDictionary);
  405. _shadowVersion = _coreVersion;
  406. }
  407. return _shadowDictionary;
  408. }
  409. }
  410. #else
  411. ReadOnlyDictionary<K, V> _shadowDictionary;
  412. public IDictionary<K, V> DictionaryItems
  413. {
  414. get
  415. {
  416. if (_shadowDictionary == null || _shadowVersion != _coreVersion)
  417. {
  418. _shadowDictionary = new ReadOnlyDictionary<K, V>(_coreDictionary);
  419. _shadowVersion = _coreVersion;
  420. }
  421. return _shadowDictionary;
  422. }
  423. }
  424. #endif
  425. }
  426. #if NETFX_CORE
  427. namespace CollectionView
  428. {
  429. public class CollectionViewIncrementalLoader<T> : ISupportIncrementalLoading
  430. {
  431. private Func<CollectionView<T>, int, Task<IncrementalLoadResult<T>>> _loadMore;
  432. private Func<CollectionView<T>, bool> _hasMore;
  433. bool _hasNoMore = false;
  434. public CollectionViewIncrementalLoader(Func<CollectionView<T>, int, Task<IncrementalLoadResult<T>>> loadMore = null, Func<CollectionView<T>, bool> hasMore = null)
  435. {
  436. var canlm = (loadMore != null);
  437. var canhm = (hasMore != null);
  438. if (canlm && canhm)
  439. {
  440. _loadMore = loadMore;
  441. _hasMore = hasMore;
  442. }
  443. else
  444. {
  445. throw new InvalidOperationException("need both loadMore and hasMore have value ");
  446. }
  447. }
  448. public CollectionView<T> CollectionView { get; set; }
  449. #region ISupportIncrementalLoading Members
  450. public bool HasMoreItems
  451. {
  452. get
  453. {
  454. if (!_hasNoMore)
  455. {
  456. _hasNoMore = !_hasMore(CollectionView);
  457. }
  458. return !_hasNoMore;
  459. }
  460. }
  461. async Task<LoadMoreItemsResult> InternalLoadMoreItemsAsync(uint count)
  462. {
  463. var rval = await _loadMore(CollectionView, (int)count);
  464. _hasNoMore = !rval.HaveMore;
  465. foreach (var x in rval.NewItems)
  466. {
  467. CollectionView.Add(x);
  468. }
  469. return new LoadMoreItemsResult { Count = count };
  470. }
  471. #endregion
  472. #region ISupportIncrementalLoading Members
  473. public Windows.Foundation.IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
  474. {
  475. return InternalLoadMoreItemsAsync(count).AsAsyncOperation();
  476. }
  477. #endregion
  478. }
  479. public struct IncrementalLoadResult<T>
  480. {
  481. public IList<T> NewItems { get; set; }
  482. public bool HaveMore { get; set; }
  483. }
  484. public class CollectionViewGroupCollectionItem : ICollectionViewGroup
  485. {
  486. public static CollectionViewGroupCollectionItem Create(object group, IObservableVector<object> items)
  487. {
  488. return new CollectionViewGroupCollectionItem(group, items);
  489. }
  490. public CollectionViewGroupCollectionItem(object group, IObservableVector<object> items)
  491. {
  492. Group = group;
  493. GroupItems = items;
  494. }
  495. public object Group { get; private set; }
  496. public IObservableVector<object> GroupItems { get; private set; }
  497. }
  498. public abstract class CollectionViewGroupCollection<TItem> : ObservableVector<CollectionViewGroupCollectionItem>
  499. {
  500. public static CollectionViewGroupCollection<TItem, TGroupKey, TGroup> Create<TGroupKey, TGroup>(Func<TItem, TGroupKey> groupKeyGetter, Func<TItem, TGroup> groupFactory, Dictionary<TGroupKey, CollectionViewGroupCollectionItem> index = null)
  501. {
  502. return new CollectionViewGroupCollection<TItem, TGroupKey, TGroup>(groupKeyGetter, groupFactory, index);
  503. }
  504. public abstract void AddItemToGroups(object item);
  505. public abstract void RemoveItemFromGroups(object item);
  506. }
  507. public class CollectionViewGroupCollection<TItem, TGroupKey, TGroup> : CollectionViewGroupCollection<TItem>
  508. {
  509. public CollectionViewGroupCollection(Func<TItem, TGroupKey> groupKeyGetter, Func<TItem, TGroup> groupFactory, Dictionary<TGroupKey, CollectionViewGroupCollectionItem> index = null)
  510. {
  511. _groupKeyGetter = groupKeyGetter;
  512. _groupFactory = groupFactory;
  513. _index = index ?? new Dictionary<TGroupKey, CollectionViewGroupCollectionItem>();
  514. }
  515. Func<TItem, TGroupKey> _groupKeyGetter;
  516. Dictionary<TGroupKey, CollectionViewGroupCollectionItem> _index;
  517. private Func<TItem, TGroup> _groupFactory;
  518. public override void AddItemToGroups(object item)
  519. {
  520. var itm = (TItem)item;
  521. var key = _groupKeyGetter(itm);
  522. CollectionViewGroupCollectionItem grp;
  523. if (!_index.TryGetValue(key, out grp))
  524. {
  525. grp = CollectionViewGroupCollectionItem.Create(_groupFactory(itm), new ObservableVector<TItem>());
  526. _index.Add(key, grp);
  527. Add(grp);
  528. }
  529. grp.GroupItems.Add(item);
  530. }
  531. public override void RemoveItemFromGroups(object item)
  532. {
  533. var key = _groupKeyGetter((TItem)item);
  534. CollectionViewGroupCollectionItem grp;
  535. if (_index.TryGetValue(key, out grp))
  536. {
  537. grp.GroupItems.Remove(item);
  538. if (grp.GroupItems.Count == 0)
  539. {
  540. _index.Remove(key);
  541. Remove(grp);
  542. }
  543. }
  544. }
  545. }
  546. /// <summary>
  547. /// <para>ICollectionView generic implmention</para>
  548. /// <para>ICollectionView 的泛型实现</para>
  549. /// </summary>
  550. /// <typeparam name="T"><para>Content Type</para><para>内容类型</para> </typeparam>
  551. public class CollectionView<T> : ObservableVector<T>, ICollectionView
  552. {
  553. /// <summary>
  554. /// <para>Constructor of Collection View</para>
  555. /// <para>构造函数</para>
  556. /// </summary>
  557. /// <param name="items"><para>Initialing Items</para><para>初始内容集合</para></param>
  558. /// <param name="loader"><para>increanatal loader</para><para>自增加载器</para></param>
  559. public CollectionView(
  560. IEnumerable<T> items = null,
  561. CollectionViewIncrementalLoader<T> loader = null)
  562. : base(items.ToArray())
  563. {
  564. items = items ?? new T[0];
  565. _loader = loader;
  566. if (loader != null)
  567. {
  568. loader.CollectionView = this;
  569. }
  570. }
  571. /// <summary>
  572. /// <para>Constructor of Collection View</para>
  573. /// <para>构造函数</para>
  574. /// </summary>
  575. /// <param name="items"><para>Initialing Items</para><para>初始内容集合</para></param>
  576. /// <param name="groupCollection"><para>Initaling Groups</para><para>初始分组</para></param>
  577. public CollectionView(
  578. IEnumerable<T> items,
  579. CollectionViewGroupCollection<T> groupCollection)
  580. : base(items.ToArray())
  581. {
  582. _group = groupCollection;
  583. if (_group != null && items != null)
  584. {
  585. foreach (var item in items)
  586. {
  587. _group.AddItemToGroups(item);
  588. }
  589. }
  590. }
  591. /// <summary>
  592. /// <para>Insert Item</para><para>插入</para>
  593. /// </summary>
  594. /// <param name="index"><para>targeting index</para><para>目标索引</para></param>
  595. /// <param name="item"><para> Item inserting</para><para>插入项</para></param>
  596. protected override void InsertItem(int index, T item)
  597. {
  598. base.InsertItem(index, item);
  599. if (_group != null)
  600. {
  601. _group.AddItemToGroups(item);
  602. }
  603. }
  604. protected override void SetItem(int index, T item)
  605. {
  606. var oldItem = base.Items[index];
  607. if (_group != null)
  608. {
  609. _group.RemoveItemFromGroups(item);
  610. }
  611. base.SetItem(index, item);
  612. if (_group != null)
  613. {
  614. _group.AddItemToGroups(item);
  615. }
  616. }
  617. /// <summary>
  618. /// <para>Clear Items</para>
  619. /// <para>清除内容</para>
  620. /// </summary>
  621. protected override void ClearItems()
  622. {
  623. base.ClearItems();
  624. if (_group != null)
  625. {
  626. _group.Clear();
  627. }
  628. }
  629. protected override void RemoveItem(int index)
  630. {
  631. var olditem = base.Items[index];
  632. base.RemoveItem(index);
  633. if (_group != null)
  634. {
  635. _group.RemoveItemFromGroups(olditem);
  636. }
  637. }
  638. /// <summary>
  639. /// <para>Incremental Loader</para>
  640. /// <para>自增读取器</para>
  641. /// </summary>
  642. protected CollectionViewIncrementalLoader<T> _loader;
  643. Windows.Foundation.Collections.IObservableVector<object> ThisVector { get { return this; } }
  644. #region ICollectionView Members
  645. private CollectionViewGroupCollection<T> _group;
  646. /// <summary>
  647. /// <para>Collection Groups</para>
  648. /// <para>集合中的分组</para>
  649. /// </summary>
  650. public Windows.Foundation.Collections.IObservableVector<object> CollectionGroups
  651. {
  652. get { return _group; }
  653. }
  654. /// <summary>
  655. /// <para>Fired when current Item has changed</para>
  656. /// <para>当前项变化后触发</para>
  657. /// </summary>
  658. public event EventHandler<object> CurrentChanged;
  659. /// <summary>
  660. /// <para>Fired when current Item is changing</para>
  661. /// <para>当前项变化前触发</para>
  662. /// </summary>
  663. public event CurrentChangingEventHandler CurrentChanging;
  664. /// <summary>
  665. /// <para>Current Item </para>
  666. /// <para>当前项</para
  667. /// </summary>
  668. public object CurrentItem
  669. {
  670. get
  671. {
  672. if (Count > _CurrentPosition && _CurrentPosition >= 0)
  673. {
  674. return Items[_CurrentPosition];
  675. }
  676. return null;
  677. }
  678. }
  679. int _CurrentPosition = 0;
  680. /// <summary>
  681. /// <para>Current Item Index</para><para>当前项的索引</para>
  682. /// </summary>
  683. public int CurrentPosition
  684. {
  685. get { return _CurrentPosition; }
  686. set
  687. {
  688. _CurrentPosition = value;
  689. base.OnPropertyChanged("CurrentPosition");
  690. base.OnPropertyChanged("CurrentItem");
  691. }
  692. }
  693. /// <summary>
  694. /// <para>Has more items can loaded by loader</para><para>是否还有更多的数据</para>
  695. /// </summary>
  696. public bool HasMoreItems
  697. {
  698. get
  699. {
  700. if (_loader == null)
  701. {
  702. return false;
  703. }
  704. else
  705. {
  706. return _loader.HasMoreItems;
  707. }
  708. }
  709. }
  710. /// <summary>
  711. /// <para>Is Current Item is beyond bound of collection</para><para>当前项目是否已经超出集合最大范围</para>
  712. /// </summary>
  713. public bool IsCurrentAfterLast
  714. {
  715. get { return _CurrentPosition >= this.Count; }
  716. }
  717. /// <summary>
  718. /// <para>Is Current Item is before bound of collection</para><para>当前项目是否已经在集合之前</para>
  719. /// </summary>
  720. public bool IsCurrentBeforeFirst
  721. {
  722. get { return _CurrentPosition < 0; }
  723. }
  724. /// <summary>
  725. /// <para>Load More Items</para><para>加载更多的项</para>
  726. /// </summary>
  727. /// <param name="count"><para>count of items</para><para>个数</para></param>
  728. /// <returns></returns>
  729. public Windows.Foundation.IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
  730. {
  731. if (_loader != null)
  732. {
  733. return _loader.LoadMoreItemsAsync(count);
  734. }
  735. else
  736. {
  737. throw new InvalidOperationException("this instance does not support load More Items");
  738. }
  739. }
  740. bool RaiseCurrentChangingAndReturnCanceled(object newValue)
  741. {
  742. if (CurrentChanging != null)
  743. {
  744. var e = new CurrentChangingEventArgs(true);
  745. CurrentChanging(this, e);
  746. return e.Cancel;
  747. }
  748. return false;
  749. }
  750. void RaiseCurrentChanged(object newValue)
  751. {
  752. if (CurrentChanged != null)
  753. {
  754. CurrentChanged(this, newValue);
  755. }
  756. base.OnPropertyChanged("CurrentItem");
  757. }
  758. public bool MoveCurrentToFirst()
  759. {
  760. var newIndex = 0;
  761. return MoveCurrentToPosition(newIndex);
  762. }
  763. public bool MoveCurrentToLast()
  764. {
  765. var newIndex = Count - 1;
  766. return MoveCurrentToPosition(newIndex);
  767. }
  768. public bool MoveCurrentToNext()
  769. {
  770. var newIndex = CurrentPosition + 1;
  771. return MoveCurrentToPosition(newIndex);
  772. }
  773. public bool MoveCurrentToPosition(int index)
  774. {
  775. if (Count > 0 && index >= 0 && index < Count)
  776. {
  777. var newVal = Items[index];
  778. if (RaiseCurrentChangingAndReturnCanceled(newVal))
  779. {
  780. CurrentPosition = index;
  781. }
  782. return true;
  783. }
  784. else
  785. {
  786. return false;
  787. }
  788. }
  789. public bool MoveCurrentToPrevious()
  790. {
  791. var newIndex = CurrentPosition - 1;
  792. return MoveCurrentToPosition(newIndex);
  793. }
  794. public bool MoveCurrentTo(object item)
  795. {
  796. var index = IndexOf((T)item);
  797. return MoveCurrentToPosition(index);
  798. }
  799. #endregion
  800. }
  801. //public class GroupedCollectionView<TGroup, TItem> : ObservableVector<TItem>
  802. //{
  803. // public GroupedCollectionView(IEnumerable<TGroup> groups, Func<IEnumerable<TGroup>, IEnumerable<TItem>> itemSelector) :
  804. // base(itemSelector(groups).ToArray())
  805. // {
  806. // }
  807. //}
  808. }
  809. #endif
  810. }
  811. }