View previous topic :: View next topic |
Author |
Message |
jaherbert
Joined: 27 Jan 2008 Posts: 43
|
Posted: Sun Jul 13, 2008 4:09 am Post subject: GetChildren and RowExpand |
|
|
I have a recursive VT based on a DataView. I'm retrieving the tree in branches via a custom RowExpand.
All binding is done at design time. I'd now like to filter rows selected by the ChildRelation based on some properties of the child. Since I can filter children of the root with the RowFilter, I'm handling GetChildren for only 1 rowBinding (rowBindingARCS_GetChildren). I'm not sure what type of object to return in e.Children. I've tried a DataView, a DataTable, and a DataRow[].
When I use a DataView, I get a bunch of DataRowView children beneath the root row. When I use a DataTable or DataRow[], I see all the rows that were initially retrieved. But I can't see any rows I add in a subsequent RowExpand.
Code: | private void GraphVirtualTree_RowExpand(object sender, RowEventArgs e) {
if (e.Row.Item is GraphDataSet.ARCSRow) {
GraphDataSet.ARCSRow ar = (GraphDataSet.ARCSRow)e.Row.Item;
if (ar.NODESRowByARCS_CHILD_FK.NUM_CHILDREN > 0) { // this node has children
if (e.Row.ChildItems == null) {
e.Row.UpdateChildren(true, true);
}
if (e.Row.ChildItems.Count < ar.NODESRowByARCS_CHILD_FK.NUM_CHILDREN) {
// We haven't retrieved all children yet.
// Add them to dataset.
}
}
}
}
void rowBindingARCS_GetChildren(object sender, GetChildrenEventArgs e) {
GraphDataSet.ARCSRow arcRow = (GraphDataSet.ARCSRow)e.Row.Item;
DataView dv = new DataView(graphDataSet.ARCS,
"TYPE <> 'D' AND PARENT_ID = " + arcRow.CHILD_ID,
TreeDataView.Sort, DataViewRowState.CurrentRows);
// DataView
e.Children = (IList)dv;
// DataRow[]
DataRow[] rows = new DataRow[dv.Count];
for (int i = 0; i < dv.Count; i++ ) {
rows[i] = dv[i].Row;
}
e.Children = (IList)rows;
// DataTable
e.Children = (IList)dv.ToTable();
}
|
Thanks for the help. |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Mon Jul 14, 2008 12:19 am Post subject: |
|
|
Ideally you would like to return a DataView, since DataViews support two way data binding via the ListChanged notification. Unfortunately DataViews contain DataRowView objects (not DataRow objects), and DataRowView objects don't support equality based on the underlying DataRow object. This would mean that VirtualTree is unable to recognise two DataRowView objects which actually have the same underlying DataView object as representing the same row.
To overcome this difficulty the standard DataRowRowBinding implementation of GetChildren a wrapper class (DataViewList) that returns the underlying DataRow objects from the DataView. You can also use this class eg
Code: | void rowBindingARCS_GetChildren(object sender, GetChildrenEventArgs e) {
GraphDataSet.ARCSRow arcRow = (GraphDataSet.ARCSRow)e.Row.Item;
DataView dv = new DataView(graphDataSet.ARCS,
"TYPE <> 'D' AND PARENT_ID = " + arcRow.CHILD_ID,
TreeDataView.Sort, DataViewRowState.CurrentRows);
e.Children = new DataViewList(dv)
} |
If you have visible columns and want to support sorting then you will need to sort the view before you return the children. To do this you can call the SortView method on the row binding for the table.
If you are trying to fill the dataset on demand (with your RowExpand handler) then I think it may be better to try and do this logic from within the GetChildren handler. To avoid GetChildren being called for each row displayed you can set the ChildPolicy for the RowBindings to LoadOnExpand. _________________ Infralution Support |
|
Back to top |
|
|
jaherbert
Joined: 27 Jan 2008 Posts: 43
|
Posted: Tue Jul 15, 2008 5:18 am Post subject: |
|
|
Thanks. The DataViewList did the trick.
Please clarify the relationship between GetChildren, RowExpand and ChildPolicy viz your last recommendation. FYI, I'm using the following code to get the Expand indicator to show the proper state.
Code: | private void GraphVirtualTree_GetChildPolicy(object sender, GetChildPolicyEventArgs e) {
if (e.Row.Item is GraphDataSet.ARCSRow) {
GraphDataSet.ARCSRow ar = (GraphDataSet.ARCSRow)e.Row.Item;
if (ar.NODESRowByARCS_CHILD_FK.NUM_CHILDREN == 0) {
e.ChildPolicy = RowChildPolicy.Normal;
} else {
e.ChildPolicy = RowChildPolicy.LoadOnExpand;
}
}
} |
Thanks. |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Tue Jul 15, 2008 8:50 am Post subject: |
|
|
Yes that GetChildPolicy handler will work the way you want. Then you could just move your logic that loads the child rows from RowExpand to GetChildren. The logic may work in RowExpand - however RowExpand is not really designed to do this work - it would be better, I think to have all the logic in GetChildren. _________________ Infralution Support |
|
Back to top |
|
|
jaherbert
Joined: 27 Jan 2008 Posts: 43
|
Posted: Tue Jul 15, 2008 6:48 pm Post subject: |
|
|
Ok. Thanks. |
|
Back to top |
|
|
|