Xaml 如何推迟绑定请求,直到项目在屏幕上可见?
我注意到在Xaml 如何推迟绑定请求,直到项目在屏幕上可见?,xaml,windows-phone-8,Xaml,Windows Phone 8,我注意到在ListBoxes和LongListSelectors上,绑定项的属性请求被延迟,直到它们被滚动到 是否可以对ScrollViewer中的自定义定位项执行相同的操作,以便该项在滚动到之前不会对其绑定属性值发出任何请求?是否有任何简单的设置可以自动执行此操作? 如果没有,那么最简单的方法是什么呢?它被称为延迟加载 这里有一个惰性列表的示例: public class LazyCollection<T> : IList<T>, IList, INotifyColle
ListBox
es和LongListSelector
s上,绑定项的属性请求被延迟,直到它们被滚动到
是否可以对ScrollViewer
中的自定义定位项执行相同的操作,以便该项在滚动到之前不会对其绑定属性值发出任何请求?是否有任何简单的设置可以自动执行此操作?如果没有,那么最简单的方法是什么呢?它被称为延迟加载 这里有一个惰性列表的示例:
public class LazyCollection<T> : IList<T>, IList, INotifyCollectionChanged, INotifyPropertyChanged
{
private const int LOAD_THRESHOLD = 3;
private ObservableCollection<T> _innerCollection;
public LazyCollection(Func<int, IEnumerable<T>> fetch)
: this(fetch, null)
{ }
public LazyCollection(Func<int, IEnumerable<T>> fetch, IEnumerable<T> items)
{
_fetch = fetch;
_innerCollection = new ObservableCollection<T>(items ?? new T[0]);
this.AttachEvents();
this.HasMoreItems = true;
}
private void AttachEvents()
{
_innerCollection.CollectionChanged += (s, e) => OnCollectionChanged(e);
((INotifyPropertyChanged)_innerCollection).PropertyChanged += (s, e) => OnPropertyChanged(e);
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, e);
}
#endregion
#region INotifyCollectionChanged
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (this.CollectionChanged != null)
this.CollectionChanged(this, e);
}
#endregion
#region IList<T>
public int IndexOf(T item)
{
return _innerCollection.IndexOf(item);
}
public void Insert(int index, T item)
{
_innerCollection.Insert(index, item);
}
public void RemoveAt(int index)
{
_innerCollection.RemoveAt(index);
}
public T this[int index]
{
get
{
Debug.WriteLine("LazyCollection - Reading item {0}", index);
return _innerCollection[index];
}
set { _innerCollection[index] = value; }
}
public void Add(T item)
{
_innerCollection.Add(item);
}
public void Clear()
{
_innerCollection.Clear();
}
public bool Contains(T item)
{
return _innerCollection.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_innerCollection.CopyTo(array, arrayIndex);
}
public int Count
{
get { return _innerCollection.Count; }
}
public bool IsReadOnly
{
get { return ((IList<T>)_innerCollection).IsReadOnly; }
}
public bool Remove(T item)
{
return _innerCollection.Remove(item);
}
public IEnumerator<T> GetEnumerator()
{
Debug.WriteLine("LazyCollection - GetEnumerator");
return _innerCollection.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
Debug.WriteLine("LazyCollection - GetEnumerator explicit");
return ((IEnumerable)_innerCollection).GetEnumerator();
}
#endregion
#region IList
int IList.Add(object value)
{
return ((IList)_innerCollection).Add(value);
}
bool IList.Contains(object value)
{
return ((IList)_innerCollection).Contains(value);
}
int IList.IndexOf(object value)
{
return ((IList)_innerCollection).IndexOf(value);
}
void IList.Insert(int index, object value)
{
((IList)_innerCollection).Insert(index, value);
}
bool IList.IsFixedSize
{
get { return ((IList)_innerCollection).IsFixedSize; }
}
bool IList.IsReadOnly
{
get { return ((IList)_innerCollection).IsReadOnly; }
}
void IList.Remove(object value)
{
((IList)_innerCollection).Remove(value);
}
object IList.this[int index]
{
get
{
if (index > this.Count - LOAD_THRESHOLD)
{
this.TryLoadMoreItems();
}
Debug.WriteLine("LazyCollection - Reading item {0} IList", index);
return ((IList)_innerCollection)[index];
}
set { ((IList)_innerCollection)[index] = value; }
}
void ICollection.CopyTo(Array array, int index)
{
((IList)_innerCollection).CopyTo(array, index);
}
bool ICollection.IsSynchronized
{
get { return ((IList)_innerCollection).IsSynchronized; }
}
object ICollection.SyncRoot
{
get { return ((IList)_innerCollection).SyncRoot; }
}
#endregion
public T[] GetLoadedItems()
{
return _innerCollection.ToArray();
}
public void ResetLoadedItems(IEnumerable<T> list)
{
_innerCollection.Clear();
foreach (var i in list)
_innerCollection.Add(i);
this.HasMoreItems = true;
}
public bool HasMoreItems { get; set; }
private bool _isLoading = false;
private Func<int, IEnumerable<T>> _fetch;
private async Task TryLoadMoreItems()
{
if (_isLoading || !this.HasMoreItems)
return;
try
{
_isLoading = true;
Debug.WriteLine("LazyCollection - Loading more items skip {0}", this.Count);
List<T> items = _fetch != null ? (_fetch(Count)).ToList() : new List<T>();
if (items.Count == 0)
{
Debug.WriteLine("LazyCollection - No items returned, Loading disabled", this.Count);
this.HasMoreItems = false;
}
items.ForEach(x => _innerCollection.Add(x));
Debug.WriteLine("LazyCollection - Items added. Total count: {0}", this.Count);
}
finally
{
_isLoading = false;
}
}
}
public class SearchResults : LazyCollection<Verse>
{
public SearchResults()
: base(count => GetSearchResult(), GetSearchResult())
{
}
public static int _index = 0;
public static string CurrentSearch = "";
public static List<Verse> AllVerses = new List<Verse>();
private static List<Verse> GetSearchResult()
{
List<Verse> results = new List<Verse>();
string lower = CurrentSearch.ToLower();
bool resultsChanged = false;
for (int index = _index; index < AllVerses.Count; index++)
{
Verse verse = AllVerses[index];
if (verse.Content.ToLower().Contains(lower) || verse.Header.ToLower().Contains(lower))
{
results.Add(verse);
resultsChanged = true;
}
if ((index >= (AllVerses.Count / 200) + _index || index + 1 == AllVerses.Count) && resultsChanged && (results.Count > 10 || AllVerses.Count == index + 1))
{
_index = index + 1;
return results;
}
}
return results;
}
}
公共类LazyCollection:IList、IList、INotifyCollectionChanged、INotifyPropertyChanged
{
私有常量int LOAD_阈值=3;
私有可观测集合\u内部集合;
公共LazyCollection(Func fetch)
:this(fetch,null)
{ }
公共LazyCollection(Func fetch,IEnumerable items)
{
_fetch=fetch;
_innerCollection=新的ObservableCollection(项目??新T[0]);
这个.AttachEvents();
this.HasMoreItems=true;
}
私人无效附件()
{
_innerCollection.CollectionChanged+=(s,e)=>OnCollectionChanged(e);
((INotifyPropertyChanged)\u innerCollection.PropertyChanged+=(s,e)=>OnPropertyChanged(e);
}
#区域inotifyproperty已更改
公共事件属性更改事件处理程序属性更改;
PropertyChanged上受保护的虚拟无效(PropertyChangedEventArgs e)
{
if(this.PropertyChanged!=null)
本。财产变更(本,e);
}
#端区
#区域inotifycollection已更改
公共事件通知CollectionChangedEventHandler CollectionChanged;
CollectionChanged上受保护的虚拟空间(NotifyCollectionChangedEventArgs e)
{
如果(this.CollectionChanged!=null)
此集合已更改(此,e);
}
#端区
#区域IList
公共整数索引(T项)
{
返回_innerCollection.IndexOf(项目);
}
公共空白插入(整数索引,T项)
{
_Insert(索引,项);
}
公共无效删除(整数索引)
{
_innerCollection.RemoveAt(索引);
}
公共T此[int索引]
{
收到
{
WriteLine(“LazyCollection-读取项{0}”,索引);
返回_innerCollection[索引];
}
集合{u innerCollection[index]=value;}
}
公共作废新增(T项)
{
_innerCollection.Add(项);
}
公共空间清除()
{
_Clear();
}
公共布尔包含(T项)
{
return\u innerCollection.Contains(项目);
}
public void CopyTo(T[]数组,int arrayIndex)
{
_CopyTo(数组,arrayIndex);
}
公共整数计数
{
获取{return\u innerCollection.Count;}
}
公共图书馆是只读的
{
获取{return((IList)u innerCollection.IsReadOnly;}
}
公共布尔删除(T项)
{
返回_innerCollection.Remove(项目);
}
公共IEnumerator GetEnumerator()
{
WriteLine(“LazyCollection-GetEnumerator”);
返回_innerCollection.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
WriteLine(“LazyCollection-GetEnumerator explicit”);
return((IEnumerable)_innerCollection.GetEnumerator();
}
#端区
#区域IList
int IList.Add(对象值)
{
返回((IList)\u innerCollection.Add(value);
}
bool IList.Contains(对象值)
{
返回((IList)\u innerCollection.Contains(值);
}
int IList.IndexOf(对象值)
{
返回((IList)\u innerCollection.IndexOf(value);
}
void IList.Insert(int索引,对象值)
{
插入(索引,值);
}
bool IList.IsFixedSize
{
获取{return((IList)u innerCollection.IsFixedSize;}
}
bool-IList.IsReadOnly
{
获取{return((IList)u innerCollection.IsReadOnly;}
}
void IList.Remove(对象值)
{
((IList)u innerCollection.Remove(值);
}
对象IList。此[int索引]
{
收到
{
如果(索引>此.Count-加载\u阈值)
{
this.TryLoadMoreItems();
}
WriteLine(“LazyCollection-Reading item{0}IList”,index);
返回((IList)_innerCollection)[索引];
}
集合{((IList)_innerCollection)[index]=value;}
}
void ICollection.CopyTo(数组,int索引)
{
((IList)_innerCollection).CopyTo(数组,索引);
}
布尔ICollection.IsSynchronized
{
获取{return((IList)u innerCollection.IsSynchronized;}
}
对象ICollection.SyncRoot
{
获取{return((IList)\u innerCollection.SyncRoot;}
}
#端区
公共T[]GetLoadedItems()
{
返回_innerCollection.ToArray();
}
公共void ResetLoadedItems(IEnumerable列表)
{
_Clear();
foreach(列表中的变量i)
_添加(i);
this.HasMoreItems=true;
}
公共bool HasMoreItems{get;set;}
私有bool_isLoading=false;
私有函数获取;
专用异步任务TryLoadMoreItems()
{
如果(_isLoading | |!this.HasMoreItems)
回来
尝试
{
_isLoading=true;
WriteLine(“LazyCollection-加载更多项跳过{0}”,this.Count);
列表项=_fetch!=null?(_fetch(Count)).ToList():new List();
如果(items.Count==0)
{
Debug.WriteLine(“LazyCollection-未返回任何项,已禁用加载”,this.Count);
this.HasMoreItems=false;
}
items.ForEach(x=>_innerCollection.Add(x));
Debug.WriteLine(“LazyCollection-Items adde