【问题标题】:listBox.ItemContainerGenerator.ContainerFromItem() returns null to the NEW item added in the listboxlistBox.ItemContainerGenerator.ContainerFromItem() 将 null 返回到列表框中添加的 NEW 项
【发布时间】:2015-04-03 13:33:47
【问题描述】:

这是我在这里的第一篇文章,所以我希望你能帮助我解决关于 WPF 的问题。

我有一个与 ObservableCollection 绑定的列表框:

    public ObservableCollection<DeviceSetting> DeviceSettings
                {
                    get { return _deviceSettings; }
                    set { _deviceSettings = value; }
                }

   <ListBox ItemTemplate="{StaticResource IPItemTemplate}" Name="listBoxAddresses" SelectionMode="Extended" ItemsSource="{Binding Path=TestSetting.DeviceSettings, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
     ItemContainerStyle="{StaticResource ContainerStyle}" />

这里的情况是,我想知道一个新项目是否已添加到列表中,所以我所做的是创建一个 CollectionChanged 事件:

TestSetting.DeviceSettings.CollectionChanged += mListBox_CollectionChanged;  

private void mListBox_CollectionChanged(object sender,NotifyCollectionChangedEventArgs e)
{
   if (e.Action == NotifyCollectionChangedAction.Add)
   {
       for (int i = 0; i < TestSetting.DeviceSettings.Count; i++){

       ListBoxItem myListBoxItem = (ListBoxItem)(listBoxAddresses.ItemContainerGenerator.ContainerFromItem(listBoxAddresses.Items[i]));


        if (!TestSetting.DeviceSettings[i].IsNetwork && DeviceDiscovery.IsSelected)
                  myListBoxItem.IsEnabled = false;

        else if (TestSetting.DeviceSettings[i].IsNetwork && !DeviceDiscovery.IsSelected)
                  myListBoxItem.IsEnabled = false;
        else
                  myListBoxItem.IsEnabled = true;

     }
 }

但是这个语句出现了问题:

ListBoxItem myListBoxItem = (ListBoxItem)(listBoxAddresses.ItemContainerGenerator.ContainerFromItem(listBoxAddresses.Items[i]));

每次我添加一个新项目时,上面的语句总是返回 null,因此不会检查添加的新项目是否会启用。有没有办法让这个语句返回我需要的正确 ListBoxItem?

【问题讨论】:

  • 为什么不在 ItemTemplate 中使用绑定(借助一些转换器)?无论如何,您正在检查属性,您现在只能手动执行此操作。

标签: wpf


【解决方案1】:

您正在处理底层集合CollectionChanged 事件。仅仅因为更改了集合并不意味着该项目已被渲染并且UIElement 已准备好。

注册ItemsGenerator.StatusChanged 事件,该事件应保证UIElement 已准备就绪。

【讨论】:

  • 感谢您的回复。那么这是否意味着我应该注册 ItemContainerGenerator.StatusChanged 而不是 CollectionChanged 事件?我应该将我的项目启用逻辑放在哪里?
  • 无论如何,非常感谢我自己想通了。代替 CollectionChanged 事件,ItemContainerGenerator.StatusChanged 就足够了,并将我的逻辑移至此事件。谢谢亚伦
【解决方案2】:

我没有在 Windows Phone 中找到 ItemsGenerator.StatusChanged 事件,但它与 listBoxAddresses.LayoutUpdated 一起使用

我还必须确保 myListBoxItem 与 null 不同。

【讨论】:

    【解决方案3】:

    如果您正在加载控件并尝试访问...

    ItemContainerGenerator.ContainerFromItem(object here)
    

    我能够通过在我的 ListBox.Loaded 事件中解决此问题。例如

    SourceColumnListBox.Loaded += SourceColumnListBox_Loaded;
    

    然后在 SourceColumnListBox_Loaded 处理程序中,一切正常。

    【讨论】:

      猜你喜欢
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 2014-01-23
      相关资源
      最近更新 更多