开发者

ItemsControl ItemsSource lazy loading

开发者 https://www.devze.com 2023-04-09 12:58 出处:网络
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),

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号