ItemsControl ItemsSource 延迟加载
想象一下,您正在创建一个行为类似于 WPF 中的 ComboBox
的自定义控件。 作为您提供 IQueryable
(或任何类型的 IEnumerable
集合)的项目来源, 但您不希望允许控件调用 GetIterator()
并迭代它(某种延迟加载)。
假设您继承了(因为您想要该控件的所有功能)
System.Windows.Controls.Primitives.Selector
类。 Selector 类继承自 System.Windows.Controls.ItemsControl 类,该类提供了众所周知的依赖属性 ItemsSource。
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(ItemsControl),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(ItemsControl.OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ItemsControl control = (ItemsControl) d;
IEnumerable oldValue = (IEnumerable) e.OldValue;
IEnumerable newValue = (IEnumerable) e.NewValue;
ItemValueStorageField.ClearValue(d);
if ((e.NewValue == null) && !BindingOperations.IsDataBound(d, ItemsSourceProperty))
{
control.Items.ClearItemsSource();
}
else
{
control.Items.SetItemsSource(newValue); // PROBLEM
}
control.OnItemsSourceChanged(oldValue, newValue);
}
如果我没看错的话,这就是它迭代的地方。
internal void SetItemsSource(IEnumerable value)
{
if ((!this.IsUsingItemsSource && (this._internalView != null)) && (this._internalView.RawCount > 0))
{
throw new InvalidOperationException(SR.Get("CannotUseItemsSource"));
}
this._itemsSource = value;
this._isUsingItemsSource = true;
this.SetCollectionView(CollectionViewSource.GetDefaultCollectionView(this._itemsSource, this.ModelParent));
}
所以我决定重写 ItemsSourceProperty 的元数据并将其指向我自己的静态方法, 我计划不共同调用 SetItemsSource
(而是延迟它)。
您认为应该如何做?
谢谢
Image you are creating a custom control behaving like ComboBox
in WPF.
As a source of items you provide IQueryable<T>
(or any kind of IEnumerable
collection),
but you don't want to allow the control to call GetIterator()
and iterate through it (some kind of a lazy loading).
Let's say you inherit from the (because you want all the funcionality of that control)
System.Windows.Controls.Primitives.Selector
class.
The Selector class inherits from System.Windows.Controls.ItemsControl class which provides a the well known dependency property ItemsSource.
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(ItemsControl),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(ItemsControl.OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ItemsControl control = (ItemsControl) d;
IEnumerable oldValue = (IEnumerable) e.OldValue;
IEnumerable newValue = (IEnumerable) e.NewValue;
ItemValueStorageField.ClearValue(d);
if ((e.NewValue == null) && !BindingOperations.IsDataBound(d, ItemsSourceProperty))
{
control.Items.ClearItemsSource();
}
else
{
control.Items.SetItemsSource(newValue); // PROBLEM
}
control.OnItemsSourceChanged(oldValue, newValue);
}
If I see it correctly, this is the place where it iterates.
internal void SetItemsSource(IEnumerable value)
{
if ((!this.IsUsingItemsSource && (this._internalView != null)) && (this._internalView.RawCount > 0))
{
throw new InvalidOperationException(SR.Get("CannotUseItemsSource"));
}
this._itemsSource = value;
this._isUsingItemsSource = true;
this.SetCollectionView(CollectionViewSource.GetDefaultCollectionView(this._itemsSource, this.ModelParent));
}
So I've decided to override metadata of ItemsSourceProperty and point it to my own static method,
where I'm planing not co call SetItemsSource
(rather delay it).
How should it be done in your opinion?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最好的选择可能是添加一个新的依赖属性,例如
IEnumerable
类型的DelayedItemsSource
。然后,您可以在延迟后将ItemsSource
绑定到DelayedItemsSource
。Your best bet would be to probably add a new dependency property, say
DelayedItemsSource
of typeIEnumerable
. Then you could bindItemsSource
toDelayedItemsSource
after your delay.