So I need to databind again because of stored procedures running on the database, and I need to show those changes in the grid.
Running databind again works, but you loose the expanded rows, selected rows etc.
So surely theres a way to re-read the data from the dataset without databind?.
Thanks.
Perfect - this works really fine !!!
It looks like you aren't using a Heirarchical grid of more than 1 level, but if you are this expansion code should work:
private static void RestoreExpandedState(UltraWebGrid ultraWebGrid, List<RowIndex> _expandedRows){ RowsCollection rows = ultraWebGrid.Rows; RestoreExpandedStateRecursive(_expandedRows, rows);
}
private static void RestoreExpandedStateRecursive(List<RowIndex> rowIndexes, RowsCollection rows){ foreach (UltraGridRow row in rows) { RowIndex rowIndexFromList = GetRowIndexFromExpandedList(rowIndexes, row);
if (rowIndexFromList != null) { row.Expand(false); if (row.Rows != null) { RestoreExpandedStateRecursive(rowIndexFromList.ChildIndexes, row.Rows);
} } }}
private static List<RowIndex> StoreExpandedState(UltraWebGrid ultraWebGrid){ int level = 0; RowsCollection rows = ultraWebGrid.Rows;
List<RowIndex> _expandedRows = new List<RowIndex>();
StoreExpandedStateRecursive(_expandedRows, level, rows);
return _expandedRows;}
private static void StoreExpandedStateRecursive(List<RowIndex> _expandedRows, int level, RowsCollection rows){ foreach (UltraGridRow row in rows) { if (row.Expanded) { List<RowIndex> childIndexes = new List<RowIndex>(); StoreExpandedStateRecursive(childIndexes, level + 1, row.Rows);
RowIndex rowIndex = new RowIndex(level, row.Index, childIndexes); _expandedRows.Add(rowIndex);
} }}
private static RowIndex GetRowIndexFromExpandedList(List<RowIndex> rowIndexes, UltraGridRow row){ return rowIndexes.Find(delegate(RowIndex rowIndex) { return row.Index == rowIndex.Index; });}
class RowIndex{ private int _Level; private int _Index;
private List<RowIndex> _ChildIndexes; public RowIndex(int level, int index, List<RowIndex> childIndexes) { _Level = level; _Index = index; _ChildIndexes = childIndexes; }
public int Index { get { return _Index; } set { _Index = value; } }
public int Level { get { return _Level; } set { _Level = value; } }
public List<RowIndex> ChildIndexes { get { return _ChildIndexes; } set { _ChildIndexes = value; } }}
mleevisiphor,
Thanks heaps for that.
Last night though I came up with the 2 solutions myself ... basically the same as what you said.I can't believe the grid can't do this though, this is just the best of a bad situation.
1. Re-fresh the data maually line by line, cell by cell.2. Store thee expanded rows (also you could do the same for selected rows, but I didn't this was pain enough.)
I implemented both solutions because I am maintaining someone elses code and its a dogs breakfast, and solution 1 couldn't be used in all cases (don't ask :) )
I'll provide them here in cause anyone wants examples:
1.
public void refreshDataset() { //UltraWebGrid1.DisplayLayout.Grid. DataSet ds = (DataSet)Session["ds"]; DataTable dtQuote = new DataTable(); //dtQuote.Clear(); myAdapter = quote.GetTempTableNetworkingAdap(lblSessionID.Text); myAdapter.Fill(dtQuote); refreshDatasetWorker(dtQuote, 1); } public void refreshDatasetWorker(DataTable dat, int band) { Infragistics.WebUI.UltraWebGrid.UltraGridRow row; IEnumerator en = UltraWebGrid1.DisplayLayout.Bands[band].GetRowsEnumerator(); while (en.MoveNext()) { row = (Infragistics.WebUI.UltraWebGrid.UltraGridRow)en.Current; String ind = UltraWebGrid1.DisplayLayout.Bands[band].DataKeyField; int j = 0; Boolean foundRowInDataTable = false; for (j = 0; j < dat.Rows.Count; j++) { String trans2 = dat.Rows[j][ind].ToString(); String trans1 = row.Cells.FromKey(ind).Value.ToString(); if (trans1.Equals(trans2)) { foundRowInDataTable = true; break; } } if (foundRowInDataTable) { for (int i = 0; i < row.Cells.Count; i++) { String colKey = row.Cells.Key; row.Cells.FromKey(colKey).Value = dat.Rows[j][colKey].ToString(); } } } }
2.
usage:
ArrayList ar = getExpandedRowsFirstBand(); this.BuildGrid(); this.UltraWebGrid1.DataBind(); setExpandedRowsFirstBand(ar);
/* This function when used in conjunction with setExpandedRowsFirstBand is to overcome the problem of using databind to refresh the data for the ulrawebgrid. Until they provide a better way to refresh the data, its also nessecary because of badly written code in this page. Otherwise the other work around refreshDataset() would have been used, as it is else where. */ public ArrayList getExpandedRowsFirstBand() { Infragistics.WebUI.UltraWebGrid.UltraGridRow row; IEnumerator en = UltraWebGrid1.DisplayLayout.Bands[0].GetRowsEnumerator(); ArrayList ar = new ArrayList(); while (en.MoveNext()) { row = (Infragistics.WebUI.UltraWebGrid.UltraGridRow)en.Current; if (row.Expanded) { ar.Add(row.Index); } } return ar; } public void setExpandedRowsFirstBand(ArrayList ar) { Infragistics.WebUI.UltraWebGrid.UltraGridRow row; IEnumerator en = UltraWebGrid1.DisplayLayout.Bands[0].GetRowsEnumerator(); int i = 0; IEnumerator iar = ar.GetEnumerator(); while (iar.MoveNext()) { UltraWebGrid1.Rows[(int)iar.Current].Expand(true); } }
I had this problem and found two workaround. One was to store the expanded state before databind and then restore it after. The other was to write my own "re-databind" function. Attached is the re-databind function. I'd have to do some digging in the history of the project for the expand store/restore code 'cause it's deleted now but I'll look it up if the "re-databind" doesn't work for you.
The only issue is that it doesn't handle new rows right now. It should be fairly easy to modify to allow it to pickup new rows.
protected static void RecursiveUpdateRows(DataSet updatedDataSet, RowsCollection rows, int level) { DataTable tableToReadFrom = updatedDataSet.Tables[level]; foreach (UltraGridRow row in rows) { UpdateUltraGridRowFromDataTable(tableToReadFrom, row); if (row.HasChildRows == true) { RecursiveUpdateRows(updatedDataSet, row.Rows, level + 1); } } }
private static void UpdateUltraGridRowFromDataTable(DataTable tableToReadFrom, UltraGridRow rowToUpdate) { int rowIndex = (int)rowToUpdate.Cells[0].Value;
DataRowView updatedRow = tableToReadFrom.DefaultView[rowIndex];
foreach (UltraGridCell cell in rowToUpdate.Cells) { string columnName = cell.Column.BaseColumnName; object cellValue = cell.Value; if (cellValue == null) { if (updatedRow[columnName] != null && updatedRow[columnName] != DBNull.Value) { cell.Value = updatedRow[columnName]; } } else if (cell.Value.Equals(updatedRow[columnName]) == false) { cell.Value = updatedRow[columnName]; } } }
Edit: Fixed the formatting of the code. It also appeared that I was missing the function declaration of the first function.