Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 已创建dCellChecked。 在Expand()的第二级调用期间,ChildCellChecked为null。这将导致一个异常_C#_Event Handling_C1flexgrid - Fatal编程技术网

C# 已创建dCellChecked。 在Expand()的第二级调用期间,ChildCellChecked为null。这将导致一个异常

C# 已创建dCellChecked。 在Expand()的第二级调用期间,ChildCellChecked为null。这将导致一个异常,c#,event-handling,c1flexgrid,C#,Event Handling,C1flexgrid,我不明白为什么在对Expand()的第二级调用期间,委托ChildCellChecked为null 附加的屏幕截图可以更好地显示错误。。。 在调试模式下拍摄2个屏幕截图 第一个网格被扩展。 此时父栅格将展开为第一个子栅格。 您可以看到这两个事件都已定义。仅创建了ChildCellCheck。 第二个网格被扩展。 展开第一个子网格以显示第二级网格时,出现以下错误: 实际上,在第一次调用Expand()期间,两个委托都与各自的事件方法相关联。在第二次调用Expand()期间,两个委托都为null

我不明白为什么在对Expand()的第二级调用期间,委托ChildCellChecked为null

附加的屏幕截图可以更好地显示错误。。。 在调试模式下拍摄2个屏幕截图

第一个网格被扩展。 此时父栅格将展开为第一个子栅格。 您可以看到这两个事件都已定义。仅创建了ChildCellCheck。

第二个网格被扩展。 展开第一个子网格以显示第二级网格时,出现以下错误:

实际上,在第一次调用Expand()期间,两个委托都与各自的事件方法相关联。在第二次调用Expand()期间,两个委托都为null

我原以为,当创建子网格时,不管级别如何,都会为该子网格创建一个事件处理程序。对于第二级网格,我不需要第二个事件处理程序。单击复选框时,将触发事件,并且在事件方法中,您可以确定触发事件的子网格级别


Gloria

正如我在你原来的帖子上所说:-

请参阅以下评论:

  • 展开节点时,会将子网格添加到父节点的控件集合中。类似地,折叠行时,子网格将从父网格的控件集合中删除。移除子网格时,将清除子网格的HeaderGrid的UserData。因此,它将使事件处理程序完全无效。这就是为什么这个片段不能直接工作的原因

  • 如果在为每个网格添加事件之前展开所有行,那么在每行只有一个子项的情况下,它将非常有效。但是,这不适用于更一般的情况,因为只有一个孩子的事件发生时,所有孩子都会被称为“儿童事件”

  • 正如您尝试实现的那样,最好的情况肯定是在DataTree类的ExpandRow方法中添加子事件。这样,无论何时展开行或创建网格,事件处理程序都会附加到网格。可以执行检查,查看当前网格是否应与“child”或“child的child”事件链接。请参阅以下代码段:

     int level = 0;
     C1FlexDataTree parent = new C1FlexDataTree();
     parent = childGrid;
     while (parent.Parent is C1FlexDataTree)
     {
     parent = parent.Parent as C1FlexDataTree;
     level++;
     }
     if (level ==  1)
     {
     childGrid.CellChecked += new RowColEventHandler(child_CellChecked);
     }
     else if (level == 2)
     {
     childGrid.CellChecked += new RowColEventHandler(childchild_CellChecked);
     }
    
    protected override void OnCellChecked(RowColEventArgs e)
    {
        base.OnCellChecked(e);
        // Access childs from a flex data tree
        if (this.Rows[e.Row].UserData != null)
        {
            C1FlexDataTree child = this.Rows[e.Row].UserData as C1FlexDataTree;
            foreach (Row childRow in child.Rows)
            {
                if (childRow.Index > 0)
                {
                    childRow[1] = this.Rows[e.Row][1];
                    if (childRow.UserData != null)
                    {
                        C1FlexDataTree childchild = childRow.UserData as C1FlexDataTree;
                        foreach (Row childchildRow in childchild.Rows)
                        {
                            if (childchildRow.Index > 0)
                            childchildRow[1] = this.Rows[e.Row][1];
                        }
                    }
                }
            }
        }
        // Check the level of grid
        C1FlexDataTree parent = this;
        int level = 0;
        while (parent.Parent is C1FlexDataTree)
        {
            level++;
            parent = parent.Parent as C1FlexDataTree;
        }
    
        if (level == 0)
        {
            MessageBox.Show("I am parent");
            // Place your code for ParentCellChecked here
        }
        else if (level == 1)
        {
            MessageBox.Show("I am parent’s child");
            // Place your code for ChildCellChecked here
        }
        else if (level == 2)
        {
            MessageBox.Show("I am parent’s child’s child");
            // Place your code for ChildChildCellChecked here
        }
    
    }
    
  • 在代码段中,您正在检查childGrid.Rows[row]的UserData是否为空。但是childGrid行的UserData总是空的。每当将子格线添加到格线时,子格线的每一行都会折叠或不可展开

  • 提示:如果某行的UserData为null,则表示该行已折叠或该行没有任何子网格

    在第三点中,我们为“childs”和“childs of childs”创建了事件。这不会为父网格创建事件。因此,您可能必须在DataTree类的构造函数中添加一个代码段

     if (this.ParentGrid == this)
     {
          this.CellChecked+=new RowColEventHandler(Parent_CellChecked);
     }
    
重要


父网格中的所有子网格都将是一个数据树。这就是为什么扩展每个子网格的行也会触发ExpandRow方法,并最终尝试添加事件处理程序。请采取正确的措施确保ChildGrid的ExpandRow方法不会添加类似父网格的事件。这可以通过检查childGrid的级别来确保。它在步骤3中执行。

请注意,每次创建数据树时,所有嵌入式网格(父对象的子对象)都会实现相同的事件。因此,在同一个数据树类中创建ParentCheckChildCheckChildCheck事件是不对的。这就是为什么当我们在数据树类中创建ParentCheckChildCheckChildCheck事件时,即使是子级也会执行ChildCheck事件

当在数据树类中创建CellChecked事件时,可以观察到所有网格都继承了CellChecked事件。这是一个非常有利的情况,我们所要做的就是确定网格的层次结构

复选框的实现是放置事件的最重要部分。由于复选框只不过是一个布尔列,而不是字形嵌入的控件(在一些联机示例中实现),因此复选框不需要与事件单独链接,因此,可以通过覆盖基本的CellChecked事件来实现CellChecked事件

请参阅以下代码段:

 int level = 0;
 C1FlexDataTree parent = new C1FlexDataTree();
 parent = childGrid;
 while (parent.Parent is C1FlexDataTree)
 {
 parent = parent.Parent as C1FlexDataTree;
 level++;
 }
 if (level ==  1)
 {
 childGrid.CellChecked += new RowColEventHandler(child_CellChecked);
 }
 else if (level == 2)
 {
 childGrid.CellChecked += new RowColEventHandler(childchild_CellChecked);
 }
protected override void OnCellChecked(RowColEventArgs e)
{
    base.OnCellChecked(e);
    // Access childs from a flex data tree
    if (this.Rows[e.Row].UserData != null)
    {
        C1FlexDataTree child = this.Rows[e.Row].UserData as C1FlexDataTree;
        foreach (Row childRow in child.Rows)
        {
            if (childRow.Index > 0)
            {
                childRow[1] = this.Rows[e.Row][1];
                if (childRow.UserData != null)
                {
                    C1FlexDataTree childchild = childRow.UserData as C1FlexDataTree;
                    foreach (Row childchildRow in childchild.Rows)
                    {
                        if (childchildRow.Index > 0)
                        childchildRow[1] = this.Rows[e.Row][1];
                    }
                }
            }
        }
    }
    // Check the level of grid
    C1FlexDataTree parent = this;
    int level = 0;
    while (parent.Parent is C1FlexDataTree)
    {
        level++;
        parent = parent.Parent as C1FlexDataTree;
    }

    if (level == 0)
    {
        MessageBox.Show("I am parent");
        // Place your code for ParentCellChecked here
    }
    else if (level == 1)
    {
        MessageBox.Show("I am parent’s child");
        // Place your code for ChildCellChecked here
    }
    else if (level == 2)
    {
        MessageBox.Show("I am parent’s child’s child");
        // Place your code for ChildChildCellChecked here
    }

}
请注意,在上面的代码段中,必须实现ParentCellCheckedChildCellCheckedChildCellChecked

也可以访问父网格的子网格的子网格…等等,如果我们可以访问父网格的话。下面的代码片段描述了这一点。请注意,子网格不能来自创建父网格的类。最好在DataTree类本身中使用此代码段

if (this.Rows[XthRow].UserData != null)
{
    C1FlexDataTree child = this.Rows[e.Row].UserData as C1FlexDataTree;
    foreach (Row childRow in child.Rows)
    {
        if (childRow.Index > 0)
        {
            // ALL THE CHILD’S ROW
            if (childRow.UserData != null)
            {
                C1FlexDataTree childchild = childRow.UserData as C1FlexDataTree;
                foreach (Row childchildRow in childchild.Rows)
                {
                    if (childchildRow.Index > 0)
                         // ALL THE CHILD’S CHILD’S ROW
                }
            }
        }
    }
}

我更新了演示错误的示例代码。你能更改我发送的代码以显示你的解释是如何工作的吗?