我正在使用来自 ComponentOne 的 DataTree Grid。目前,DataTree 网格有 2 个级别(父级和子级)。每个网格中的每一行都有一个复选框列,用户可以“选择”该行。当用户选择父行时触发事件,flexgrid_CellChecked。当子网格被选中时,触发的事件是 flexgrid_ChildCellChecked。我想向 DataTree 添加第 3 级,并在选择最内层网格中的复选框时触发相应的事件。我们称它为 flexgrid_ChildChildCellChecked。
此事件在 DataTree 类中的 Expand (int row) 方法期间实例化。问题是当第一个孩子(级别 2)展开时,事件 ChildCellChecked 和 ChildChildCellChecked 可以添加为处理程序。当第二个孩子(第 3 级)展开时,这两个事件都为空。
这是具有 Expand 方法的 DataTree 类:
public class C1FlexDataTree : C1FlexGrid, ISupportInitialize
{
//--------------------------------------------------------------------------------
#region ** fields
// reference to hidden column that contains details rows for each master record
//
// this is created automatically by a DataSet based on its Relations.
//
// e.g. if the parent table is 'Orders', this could be an 'OrderDetails' table
// with the order details for each order on the master data table.
//
private Column _colChild = null;
// child grid that displays the headers rows over the native header rows.
//
// this grid appears on top of all child controls and prevents children from
// hiding the parent grid's header rows when they scroll.
//
private GridHeader _hdr = null; // <<1.1>>
// fire event to allow setting up child grids
// the event sender is the child grid that was just bound
public event EventHandler SetupColumns;
public event RowColEventHandler ChildCellChecked;
public event RowColEventHandler ChildChildCellChecked;
protected virtual void OnSetupColumns(object sender)
{
if (SetupColumns != null)
SetupColumns(sender, EventArgs.Empty);
}
protected virtual void OnChildCellChecked(object sender, RowColEventArgs e)
{
if (ChildCellChecked != null)
{
ChildCellChecked(sender, e);
}
}
protected virtual void OnChildChildCellChecked(object sender, RowColEventArgs e)
{
if (ChildChildCellChecked != null)
{
ChildChildCellChecked(sender, e);
}
}
// get top-level grid (overall parent)
public C1FlexDataTree ParentGrid
{
get
{
C1FlexDataTree parent = this;
while (parent.Parent is C1FlexDataTree)
parent = parent.Parent as C1FlexDataTree;
return parent;
}
}
// expand row
public bool ExpandRow(int row)
{
// sanity
if (row < Rows.Fixed || row >= Rows.Count)
{
return false;
}
// check that the row is not already expanded
C1FlexDataTree childGrid = Rows[row].UserData as C1FlexDataTree;
if (childGrid != null)
{
return false;
}
// check that we have a data source for this row
object dataSource = _colChild != null? _colChild[row] : null;
if (!(dataSource is IBindingList))
{
return false;
}
// ** fire before collapse event
var e = new RowColEventArgs(row, -1);
OnBeforeCollapse(e);
if (e.Cancel)
{
return false;
}
// add node row (unbound) to display child
Rows.InsertNode(row + 1, -1);
// make new row non-editable (it's just a placeholder)
Rows[row + 1].AllowEditing = false;
// create child grid
childGrid = new C1FlexDataTree();
childGrid.Visible = false;
childGrid.ScrollBars = ScrollBars.Horizontal;
// hook up event handlers
//When there is only 2 levels this 'if' statement is not needed.
//But with 3 levels, the ChildCellChecked is null
if (ChildCellChecked != null)
{
childGrid.CellChecked += new RowColEventHandler(ChildCellChecked);
}
// attach child grid to parent, set data source
Controls.Add(childGrid);
childGrid.DataSource = dataSource;
// save references:
// child grid Tag property contains a reference to the parent row
// parent row UserData contains a reference to the child grid
childGrid.Tag = Rows[row];
Rows[row].UserData = childGrid;
// make child grid visible, move it into position
childGrid.Visible = true;
childGrid.UpdatePosition();
childGrid.Focus();
//When _colChild is null, the 3rd level is being expanded.
//ChildChildCellChecked is null
if (childGrid._colChild == null)
{
childGrid.CellChecked += new RowColEventHandler(ChildChildCellChecked);
}
OnAfterCollapse(e);
// done
return true;
}
我想创建事件,ChildCellChecked 用于第二级网格,ChildChildCellChecked 用于第三级网格。
网格显示正确,可以展开和折叠。但是当我单击第三级网格中的复选框时,不会触发任何事件。
如何将事件处理程序与每个级别网格相关联?
更新
使用您的代码片段之一来识别正在扩展的级别,当级别为 2 时,事件 ChildChildCellChecked 为空。
在第一级调用和第二级调用期间调用方法 Expand() 时,我附加了一个文档以显示调试模式下的屏幕截图。
在 Expand() 的第一级调用期间,将创建 ChildCellChecked。
在 Expand() 的第二级调用期间,ChildChildCellChecked 为空。这会导致异常。
我无法弄清楚为什么在对 Expand() 的第二级调用期间委托 ChildChildCellChecked 为空。
附加的屏幕截图可以更好地显示错误...在调试模式下拍摄 2 个屏幕截图。
第一个网格被扩展。这是父网格扩展到第一个子网格的时候。您可以看到两个事件都已定义。仅创建了 ChildCellCheck。
第二个网格被扩展。当第一个子网格展开以显示第二级网格时,这是错误:
实际上,在第一次调用 Expand() 期间,两个委托都与它们各自的事件方法相关联。在第二次调用 Expand() 期间,两个委托都为空。
我会认为,当创建子网格时,无论级别如何,都会为该子网格创建一个事件处理程序。我不需要二级网格的第二个事件处理程序。单击复选框时,将触发事件,并且在事件方法中,您可以确定哪个级别的子网格触发了事件。
格洛丽亚