ItemsControl ItemsSource 延迟加载

发布于 2024-12-07 08:32:08 字数 1877 浏览 3 评论 0原文

想象一下,您正在创建一个行为类似于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月无声 2024-12-14 08:32:08

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文