【问题标题】:Unable to get LIstBoxItem from ListBox无法从 ListBox 获取 LIstBoxItem
【发布时间】:2014-05-06 17:24:15
【问题描述】:

我无法从ListBox 获得ListBoxItem。我已经动态创建了ListBox;它不在XAML 中。我刚刚设置了ItemsSource,我在所有项目中都有值,但无法将每个项目访问/转换为ListBoxItem

 for (int i = 0; i < listBox.Items.Count; i++)
            {
                ListBoxItem item = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(listBox.Items[i]);
                // item is null after above statement
            }

注意:我刚刚检查了 'listBox.ItemContainerGenerator.Status' 。 listBox.ItemContainerGenerator.Status 为“未启动”。

现在该怎么办?

【问题讨论】:

  • 你也可以发布你的 XAML
  • 你什么时候运行这个?如果你在应用程序启动时运行它,你需要先等待容器生成,然后才能像那样引用它们。
  • 我已经动态创建了 ListBox。 ListBox 的所有其他工作进展顺利。
  • 项目数大于 1 且正确。
  • 问题已更新。请看一下。

标签: c# wpf visual-studio-2010


【解决方案1】:

在调用您的方法之前,您似乎没有给 WPF 足够的时间来呈现 &lt;ListBoxItem&gt; 对象。

在设置Items 属性后立即访问ListBoxItems 的常用方法是使用ItemContainerGenerator.StatusChanged 事件,如下所示:

void MyConstructor()
{
    listBox.ItemsSource = someCollection;

    listBox.ItemContainerGenerator.StatusChanged += 
        ItemContainerGenerator_StatusChanged;
}

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
    // If containers have been generated
    if (listBox.ItemContainerGenerator.Status == 
        System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
    {
        // Remove event
        listBox.ItemContainerGenerator.StatusChanged -= 
            ItemContainerGenerator_StatusChanged;

        // Do whatever here
        foreach(var item in listBox.Items)
        {
            var item = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(item);
            // do whatever you want with the item
        }

    }
}

WPF 在不同的DispatcherPriorities 运行代码。在构造函数中或加载时运行的代码以Normal 优先级运行,而ListBoxItem 对象的生成直到Render 优先级才会发生,它在所有正常优先级项运行完毕后运行。

您也可以使用 Dispatcher 以比 Render 更高的调度程序优先级运行您的代码。

【讨论】:

  • 但是如果它是虚拟化的呢?它还没有实现每个列表框项目:D
  • 我刚刚检查了 'listBox.ItemContainerGenerator.Status' 。 listBox.ItemContainerGenerator.Status 为“未启动”
  • @Ahsan 是的,如果您愿意,您可以在StatusChanged 事件中将ItemContainerGenerator.Status 写入调试窗口,您将看到ItemContainerGenerator 经历的事件顺序。
  • 你能简单地告诉我如何生成/启动'listBox.ItemContainerGenerator'吗?
  • @Ahsan 它会在 WPF 尝试渲染 ListBox.Items 中包含的项目时自动启动。如果您对此有疑问,也许您可​​以编辑您的问题以共享您用于创建和填充 ListBox 的代码?
【解决方案2】:

为什么要将listbox 转换为listboxitem

这是一个关于获取所选项目的类似问题 listbox selected items in winform

你应该能够通过它的索引来获取项目

ListBox1.Items.Item(index)

【讨论】:

  • WPF 的工作方式与 Winforms 不同。 .Items 中存储的项目不是ListBoxItem 对象的列表,而是数据对象的列表
猜你喜欢
  • 2019-02-09
  • 2011-04-03
  • 2012-04-13
  • 1970-01-01
  • 2018-07-09
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多