如何在“bind-time”中获取ListBox中项目的ListBoxItem

时间:2010-09-09 07:04:58

标签: .net wpf data-binding listbox listboxitem

我有一个带有Foo对象的ListBox,并根据一些事件禁用/启用ListBox中的ListBoxItems。使用ListBox.Items属性我找到了Foo对象,根据我的理解,我需要使用以下函数来获取Foo的ListBoxItem容器。正确?

foreach (var item in Items)
{
    var lbi = ItemContainerGenerator.ContainerFromItem(foo) as ListBoxItem;
    // do something
}

实际上我有一个自定义控件FilteringListBox,它继承了ListBox并为它添加了一个额外的属性。上面的代码位于自定义控件的代码后面,并且在创建FilteringListBox时工作得很好。然而,我的问题是我在绑定一些属性时尝试这样做。我有一个属性FilteringCollection和一个绑定时触发的PropertyCallback。在这个回调中,我将存储FilteringCollection,但我也将进行初始过滤 - 运行set集合并禁用表示FilteringCollection中的Foo的任何ListBoxItem。

这是我遇到问题的地方。我找到了所有的Foos,所以我验证了ItemsSource的设置,但是做了ItemContainerGenerator.ContainerFromItem,我得到了null。就像ListBoxItems还没有创建一样。不是吗?这是我的约束力:

<custom:FilteringListBox ItemsSource="{Binding AvailableFoos}" FilteringCollection="{Binding AlreadyIncludedFoos}"></custom:FilteringListBox>

因此;要么:如何在“绑定时间”获取ListBoxItems?或 - 如果我不能;是否有一些我可以覆盖的事件告诉我ListBox完成创建ListBoxItems?没有运气就试过OnInitial ...

2 个答案:

答案 0 :(得分:1)

实际上,更好的解决方案似乎是使用ItemContainerGenerator。在创建时连接事件处理程序:

ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;

让事件处理程序完成需要完成的任务:

protected void ItemContainerGenerator_StatusChanged(object sender, System.EventArgs e)
{
    if (ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
        EvaluateInitialElements(); 
}

答案 1 :(得分:0)

当组件准备好呈现时触发事件OnRender,因此创建了ListBoxItem。对此事件进行初始处理过滤似乎可以确保我所需要的一切准备就绪。我评估并禁用元素,然后触发渲染:

protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
    EvaluateInitialElements();
    base.OnRender(drawingContext);
}