ItemsControl ItemsSource延迟加载

时间:2011-09-29 12:39:46

标签: wpf lazy-loading selector itemscontrol itemsource

您正在创建自定义控件的图像,其行为类似于WPF中的ComboBox。 作为您提供IQueryable<T>(或任何类型的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(而是延迟它)。

你认为应该如何做?

谢谢

1 个答案:

答案 0 :(得分:1)

您最好的选择是添加一个新的依赖项属性,比如DelayedItemsSource类型IEnumerable。然后,您可以在延迟后将ItemsSource绑定到DelayedItemsSource