【问题标题】:Why ItemContainerGenerator.ContainerFromIndex() returns null and how to avoid this behavior?为什么 ItemContainerGenerator.ContainerFromIndex() 返回 null 以及如何避免这种行为?
【发布时间】:2012-05-14 21:32:28
【问题描述】:

我正在使用这个 sn-p 来分析我在数据网格上选择的行。

for (int i = 0; i < dgDetalle.Items.Count; i++)
{
    DataGridRow row = (DataGridRow)dgDetalle.ItemContainerGenerator.ContainerFromIndex(i);
    FrameworkElement cellContent = dgDetalle.Columns[0].GetCellContent(row);
    // ... code ...
}

循环运行平稳,但是在处理某些索引时,第二行抛出了一个空异常。 MSDN 的文档说ItemContainerGenerator.ContainerFromIndex(i) 将在“如果项目未实现”时返回 null,但这并不能帮助我猜测如何获得所需的值。

如何扫描所有行?有没有其他办法?

更新

我正在使用这个 sn-p 来读取 CheckBox,正如 here 所解释的那样。所以我根本不能使用绑定或ItemSource,除非我改变了很多东西。而我不能。我正在做代码维护。

【问题讨论】:

标签: c# .net wpf datagrid datarow


【解决方案1】:

试试这个,

DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
                          grid.UpdateLayout();
            grid.ScrollIntoView(grid.Items[index]);
            row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        }

【讨论】:

  • 为我工作。谢谢!
【解决方案2】:

DataGrid 正在虚拟化项目,相应的行(即容器)仅在行在视图中时创建。

您可以turn off virtualization(如果您有很多项目,这会使第一次加载非常慢,而且内存使用率也会更高)或者您只需遍历数据并检查数据对象属性的值应该绑定到数据网格。通常你根本不需要 UI 元素...

【讨论】:

  • 我遇到了这个确切的问题,查看代码后,我们不需要 UI 元素。而是对数据进行迭代,一切正常!
【解决方案3】:

使用此订阅:

TheListBox.ItemContainerGenerator.StatusChanged += (sender, e) =>
{
  TheListBox.Dispatcher.Invoke(() =>
  {
     var TheOne = TheListBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;
       if (TheOne != null)
         // Use The One
  });
};

【讨论】:

  • 谢谢,为我工作。
【解决方案4】:

除了其他答案:控件类(页面/窗口/等)的构造函数中没有可用的项目。

如果您想在创建后访问它们,请使用Loaded 事件:

public partial class MyUserControl : UserControl
{
    public MyUserControl(int[] values)
    {
        InitializeComponent();

        this.MyItemsControl.ItemsSource = values;

        Loaded += (s, e) =>
        {
            for (int i = 0; i < this.MyItemsControl.Items.Count; ++i)
            {
                // this.MyItemsControl.ItemContainerGenerator.ContainerFromIndex(i)
            }
        };
    }
}

【讨论】:

    【解决方案5】:

    在我的情况下,grid.UpdateLayout(); 没有帮助,我需要一个 DoEvents() 代替:

        DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
    
        if (row == null)
        {
    
            WPFTools.DoEvents();
    
            grid.ScrollIntoView(grid.Items[index]);
            row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        }
    
    
        /// <summary>
        /// WPF DoEvents
        /// Source: https://stackoverflow.com/a/11899439/1574221
        /// </summary>
        public static void DoEvents()
        {
            var frame = new DispatcherFrame();
    
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                new DispatcherOperationCallback(
                    delegate (object f)
                    {
                        ((DispatcherFrame)f).Continue = false;
                        return null;
                    }), frame);
    
            Dispatcher.PushFrame(frame);
        }
    

    【讨论】:

      猜你喜欢
      • 2015-11-30
      • 1970-01-01
      • 2023-03-18
      • 2015-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      相关资源
      最近更新 更多