Hey everyone, I have a self referencing hierarchy and I am unable to configure it properly to allow editing or adding records to child nodes. If it is a top level parent both functions work perfecting. However, clicking on either the add or edit command links causes the entire child node to close and disappear. Clicking refresh on another node (but not the master table) cause the rows to reappear, including the edit/add row, but the content of those rows are empty.
I came across this post and followed it's instructions to no avail. It does not seem correct for self referencing hierarchies anyways. The relevant code from my project is below. Thanks in advance!
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server"> |
<AjaxSettings> |
<telerik:AjaxSetting AjaxControlID="TaxonomiesRadGrid"> |
<UpdatedControls> |
<telerik:AjaxUpdatedControl ControlID="TaxonomiesRadGrid" /> |
</UpdatedControls> |
</telerik:AjaxSetting> |
</AjaxSettings> |
</telerik:RadAjaxManager> |
<telerik:RadGrid runat="server" ID="TaxonomiesRadGrid" AllowMultiRowSelection="true" |
Skin="WebBlue" AutoGenerateColumns="false" Width="90%" GridLines="None" MasterTableView-DataSourceID="TaxonomiesRGSqlDataSource" |
MasterTableView-DataKeyNames="taxonomyItemId, taxonomyParentId" MasterTableView-GroupsDefaultExpanded="true" |
MasterTableView-GridLines="None" MasterTableView-GroupLoadMode="Client" MasterTableView-FilterExpression="taxonomyParentId IS NULL" |
ClientSettings-AllowGroupExpandCollapse="true" OnItemDataBound="TaxonomiesRadGrid_ItemDataBound" |
MasterTableView-SelfHierarchySettings-MaximumDepth="100" AllowAutomaticDeletes="true" |
AllowAutomaticInserts="true" AllowAutomaticUpdates="true" OnItemUpdated="TaxonomiesRadGrid_ItemUpdated" |
OnItemInserted="TaxonomiesRadGrid_ItemInserted" OnItemCreated="TaxonomiesRadGrid_ItemCreated" |
OnInsertCommand="TaxonomiesRadGrid_InsertCommand" OnUpdateCommand="TaxonomiesRadGrid_UpdateCommand" |
ShowStatusBar="true" OnDataBound="TaxonomiesRadGrid_DataBound" OnItemCommand="TaxonomiesRadGrid_ItemCommand"> |
<MasterTableView HierarchyDefaultExpanded="false" HierarchyLoadMode="Client" CommandItemDisplay="Top" |
CommandItemSettings-AddNewRecordText="Add a new Taxonomy Parent" EditMode="InPlace" |
NoMasterRecordsText="No taxonomy items to display. Please select a taxonomy framework from above."> |
<SelfHierarchySettings ParentKeyName="taxonomyParentId" KeyName="taxonomyItemId" /> |
<Columns> |
<telerik:GridBoundColumn DataField="taxonomyText" DataType="System.String" HeaderText="Taxonomy Description" |
SortExpression="taxonomyText" UniqueName="taxonomyText"> |
</telerik:GridBoundColumn> |
<telerik:GridEditCommandColumn ButtonType="PushButton" ItemStyle-Width="120px" ItemStyle-HorizontalAlign="Right"> |
</telerik:GridEditCommandColumn> |
<telerik:GridClientDeleteColumn ButtonType="PushButton" ItemStyle-Width="50px" ItemStyle-BorderWidth="0px" |
ItemStyle-HorizontalAlign="Center" ConfirmText="Are you sure you want to delete this taxonomy item and any items beneath it?"> |
</telerik:GridClientDeleteColumn> |
</Columns> |
</MasterTableView> |
</telerik:RadGrid> |
<asp:SqlDataSource ID="TaxonomiesRGSqlDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:PrimarySQLConn %>" |
SelectCommand="GetTaxonomyDetails" SelectCommandType="StoredProcedure" InsertCommand="InsertTaxonomyItem" |
InsertCommandType="StoredProcedure" UpdateCommand="UpdateTaxonomyItem" UpdateCommandType="StoredProcedure" |
OnUpdating="OnUpdating"></asp:SqlDataSource> |
Code behind:
private Hashtable _expandedState; |
private Hashtable _selectedState; |
protected void Page_Load(object sender, EventArgs e) |
{ |
if (!IsPostBack) |
{ |
//reset expanded states |
this._expandedState = null; |
this.Session["_ordersExpandedState"] = null; |
} |
} |
public void Page_PreRenderComplete(object sender, EventArgs e) |
{ |
HideExpandColumnRecursive(TaxonomiesRadGrid.MasterTableView); |
} |
#region Click & Command Events |
protected void ShowTaxonomyDetailsButton_Click(object sender, EventArgs e) |
{ |
TaxonomiesRGSqlDataSource.SelectParameters.Clear(); |
TaxonomiesRGSqlDataSource.SelectParameters.Add("id", TaxonomiesListBox.SelectedValue.ToString()); |
TaxonomiesRadGrid.DataBind(); |
} |
#endregion |
#region Grid Message |
private string gridMessage = null; |
private void SetMessage(string message) |
{ |
gridMessage = message; |
} |
protected void RadGrid1_DataBound(object sender, EventArgs e) |
{ |
if (!string.IsNullOrEmpty(gridMessage)) |
{ |
DisplayMessage(gridMessage); |
} |
} |
private void DisplayMessage(string text) |
{ |
TaxonomiesRadGrid.Controls.Add(new LiteralControl(string.Format("<span style='color:red'>{0}</span>", text))); |
} |
#endregion |
#region TaxonomiesRadGrid Events |
protected void TaxonomiesRadGrid_ItemInserted(object source, GridInsertedEventArgs e) |
{ |
if (e.Exception != null) |
{ |
e.ExceptionHandled = true; |
DisplayMessage(" Taxonomy item cannot be inserted. Reason: " + e.Exception.Message); |
} |
else |
{ |
DisplayMessage(" Taxonomy item inserted"); |
} |
} |
protected void TaxonomiesRadGrid_ItemUpdated(object source, Telerik.Web.UI.GridUpdatedEventArgs e) |
{ |
if (e.Exception != null) |
{ |
e.KeepInEditMode = false; |
e.ExceptionHandled = true; |
DisplayMessage(" Taxonomy item cannot be updated. Reason: " + e.Exception.Message); |
} |
else |
{ |
DisplayMessage(" Taxonomy item updated"); |
} |
} |
protected void TaxonomiesRadGrid_ItemCreated(object sender, GridItemEventArgs e) |
{ |
if (e.Item is GridHeaderItem && e.Item.OwnerTableView != TaxonomiesRadGrid.MasterTableView) |
{ |
e.Item.Style["display"] = "none"; |
} |
else if (e.Item is GridCommandItem && e.Item.OwnerTableView != TaxonomiesRadGrid.MasterTableView) |
{ |
((Button)e.Item.Cells[0].FindControl("AddNewRecordButton")).Visible = false; |
((Button)e.Item.Cells[0].FindControl("RefreshButton")).Visible = false; |
((LinkButton)e.Item.Cells[0].FindControl("InitInsertButton")).Text = "Add a new taxonomy item to this parent"; |
} |
else if (e.Item is GridCommandItem && e.Item.OwnerTableView == TaxonomiesRadGrid.MasterTableView) |
{ |
((Button)e.Item.Cells[0].FindControl("AddNewRecordButton")).Visible = false; |
((Button)e.Item.Cells[0].FindControl("RefreshButton")).Visible = false; |
} |
} |
protected void TaxonomiesRadGrid_InsertCommand(object source, GridCommandEventArgs e) |
{ |
if (e.Item.OwnerTableView == TaxonomiesRadGrid.MasterTableView) |
{ |
GridDataItem parentItem = (GridDataItem)e.Item.OwnerTableView.ParentItem; |
TaxonomiesRGSqlDataSource.InsertParameters.Clear(); |
TaxonomiesRGSqlDataSource.InsertParameters.Add("taxonomyId", TaxonomiesListBox.SelectedValue.ToString()); |
TaxonomiesRGSqlDataSource.InsertParameters.Add("parentId", DBNull.Value.ToString()); |
} |
else |
{ |
GridDataItem parentItem = (GridDataItem)e.Item.OwnerTableView.ParentItem; |
TaxonomiesRGSqlDataSource.InsertParameters.Clear(); |
TaxonomiesRGSqlDataSource.InsertParameters.Add("taxonomyId", TaxonomiesListBox.SelectedValue.ToString()); |
TaxonomiesRGSqlDataSource.InsertParameters.Add("parentId", parentItem.OwnerTableView.DataKeyValues[parentItem.ItemIndex]["taxonomyParentId"].ToString()); |
} |
} |
protected void TaxonomiesRadGrid_UpdateCommand(object source, GridCommandEventArgs e) |
{ |
//GridEditableItem editedItem = e.Item as GridEditableItem; |
//TaxonomiesRGSqlDataSource.UpdateParameters.Clear(); |
//TaxonomiesRGSqlDataSource.UpdateParameters.Add("taxonomyItemId", editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]["taxonomyItemId"].ToString()); |
//TaxonomiesRGSqlDataSource.UpdateParameters.Add("taxonomyText", "test"); |
} |
#endregion |
public void HideExpandColumnRecursive(GridTableView tableView) |
{ |
GridItem[] nestedViewItems = tableView.GetItems(GridItemType.NestedView); |
foreach (GridNestedViewItem nestedViewItem in nestedViewItems) |
{ |
foreach (GridTableView nestedView in nestedViewItem.NestedTableViews) |
{ |
nestedView.Style["border"] = "0"; |
Button MyExpandCollapseButton = (Button)nestedView.ParentItem.FindControl("ctl00"); |
if (nestedView.Items.Count == 0) |
{ |
if (MyExpandCollapseButton != null) |
{ |
MyExpandCollapseButton.Style["visibility"] = "hidden"; |
} |
nestedViewItem.Visible = false; |
} |
else |
{ |
if (MyExpandCollapseButton != null) |
{ |
MyExpandCollapseButton.Style.Remove("visibility"); |
} |
} |
if (nestedView.HasDetailTables) |
{ |
HideExpandColumnRecursive(nestedView); |
} |
} |
} |
} |
#region Diagnostics |
protected void OnUpdating(object sender, EventArgs e) |
{ |
EventArgs er = e; |
} |
#endregion |
#region Child Editing |
//Save/load expanded states Hash from the session |
//this can also be implemented in the ViewState |
private Hashtable ExpandedStates |
{ |
get |
{ |
if (this._expandedState == null) |
{ |
_expandedState = this.Session["_expandedState"] as Hashtable; |
if (_expandedState == null) |
{ |
_expandedState = new Hashtable(); |
this.Session["_expandedState"] = _expandedState; |
} |
} |
return this._expandedState; |
} |
} |
//Clear the state for all expanded children if a parent item is collapsed |
private void ClearExpandedChildren(string parentHierarchicalIndex) |
{ |
string[] indexes = new string[this.ExpandedStates.Keys.Count]; |
this.ExpandedStates.Keys.CopyTo(indexes, 0); |
foreach (string index in indexes) |
{ |
//all indexes of child items |
if (index.StartsWith(parentHierarchicalIndex + "_") || |
index.StartsWith(parentHierarchicalIndex + ":")) |
{ |
this.ExpandedStates.Remove(index); |
} |
} |
} |
//Save/load selected states Hash from the session |
//this can also be implemented in the ViewState |
private Hashtable SelectedStates |
{ |
get |
{ |
if (this._selectedState == null) |
{ |
_selectedState = this.Session["_selectedState"] as Hashtable; |
if (_selectedState == null) |
{ |
_selectedState = new Hashtable(); |
this.Session["_selectedState"] = _selectedState; |
} |
} |
return this._selectedState; |
} |
} |
protected void TaxonomiesRadGrid_ItemCommand(object source, GridCommandEventArgs e) |
{ |
//save the expanded/selected state in the session |
if (e.CommandName == RadGrid.ExpandCollapseCommandName) |
{ |
//Is the item about to be expanded or collapsed |
if (!e.Item.Expanded) |
{ |
//Save its unique index among all the items in the hierarchy |
this.ExpandedStates[e.Item.ItemIndexHierarchical] = true; |
} |
else //collapsed |
{ |
this.ExpandedStates.Remove(e.Item.ItemIndexHierarchical); |
this.ClearExpandedChildren(e.Item.ItemIndexHierarchical); |
} |
} |
//Is the item about to be selected |
else if (e.CommandName == RadGrid.SelectCommandName) |
{ |
//Save its unique index among all the items in the hierarchy |
this.SelectedStates[e.Item.ItemIndexHierarchical] = true; |
} |
//Is the item about to be deselected |
else if (e.CommandName == RadGrid.DeselectCommandName) |
{ |
this.SelectedStates.Remove(e.Item.ItemIndexHierarchical); |
} |
} |
protected void TaxonomiesRadGrid_DataBound(object sender, EventArgs e) |
{ |
//Expand all items using our custom storage |
string[] indexes = new string[this.ExpandedStates.Keys.Count]; |
this.ExpandedStates.Keys.CopyTo(indexes, 0); |
ArrayList arr = new ArrayList(indexes); |
//Sort so we can guarantee that a parent item is expanded before any of |
//its children |
arr.Sort(); |
foreach (string key in arr) |
{ |
bool value = (bool)this.ExpandedStates[key]; |
if (value) |
{ |
TaxonomiesRadGrid.Items[key].Expanded = true; |
} |
} |
//Select all items using our custom storage |
indexes = new string[this.SelectedStates.Keys.Count]; |
this.SelectedStates.Keys.CopyTo(indexes, 0); |
arr = new ArrayList(indexes); |
//Sort to ensure that a parent item is selected before any of its children |
arr.Sort(); |
foreach (string key in arr) |
{ |
bool value = (bool)this.SelectedStates[key]; |
if (value) |
{ |
TaxonomiesRadGrid.Items[key].Selected = true; |
} |
} |
} |
protected void grdRebind_Click(object sender, EventArgs e) |
{ |
TaxonomiesRadGrid.Rebind(); |
} |
#endregion |