ItemsControl ItemsSource lazy loading
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 th开发者_如何学编程rough 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
Your best bet would be to probably add a new dependency property, say DelayedItemsSource
of type IEnumerable
. Then you could bind ItemsSource
to DelayedItemsSource
after your delay.
精彩评论