This is a migrated thread and some comments may be shown as answers.

Self-Referencing Hierarchical Radgrid Out of Range Exception ItemHierarchicalIndex

4 Answers 89 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Kevin
Top achievements
Rank 1
Kevin asked on 14 Sep 2012, 11:04 PM
Okay so here is the problem.  I have a self-referencing grid that is setup for drag and drop.  It takes a row and it can move it up and down and it can make it a child of another row.  everything is working fine 99% of the time.  Where I run into the issue is when I close the drop down menus that show the children and then try to move a row in the grid.  Here's my code:

<script type="text/javascript">
    function gridRowDropping(sender, args) {
        var targetTable = args.get_targetItemTableView();
        if (!targetTable || targetTable.get_owner().get_id() !== sender.get_id()) {
            args.set_cancel(true);
        }
    }
</script>
 
<div id="DropUnderWrapper">
    <asp:CheckBox ID="IsUnder" runat="server" Text=" Drop Under Parent" />
</div>
<telerik:RadGrid ID="SiteMenuGrid" runat="server"
    AutoGenerateColumns="false" AllowMultiRowSelection="false"
    OnNeedDataSource="SiteMenuGrid_NeedDataSource"
    OnItemCreated="SiteMenuGrid_ItemCreated"
    OnRowDrop="SiteMenuGrid_RowDrop">
    <MasterTableView DataKeyNames="MenuID, ParentID, SortOrder" CommandItemDisplay="Top" CommandItemSettings-AddNewRecordText="Add Menu Item" HierarchyDefaultExpanded="true" HierarchyLoadMode="Client" Width="100%">
        <Columns>
            <telerik:GridDragDropColumn UniqueName="DragDropColumn" HeaderStyle-Width="20px"/>
            <telerik:GridBoundColumn DataField="MenuText" HeaderText="Name" UniqueName="Name" />
            <Telerik:GridHyperLinkColumn DataNavigateUrlFields="SitePageID" DataNavigateUrlFormatString="/admin/pageManager/?CID={0}" DataTextField="PageTitle" HeaderText="Page Title" UniqueName="PageTitle"  />
            <telerik:GridBoundColumn DataField="MenuUrl" HeaderText="Url" UniqueName="MenuUrl" />
            <telerik:GridBoundColumn DataField="MenuTarget" HeaderText="Target" UniqueName="MenuTarget" />
            <telerik:GridBoundColumn DataField="IsEnabled" HeaderText="Status" UniqueName="MenuItemEnabled" />
            <telerik:GridEditCommandColumn ButtonType="ImageButton" HeaderStyle-Width="20px" />
            <telerik:GridButtonColumn ConfirmText="Delete this product?" ConfirmDialogType="RadWindow" ConfirmTitle="Delete" ButtonType="ImageButton" CommandName="Delete" HeaderStyle-Width="20px" />
        </Columns>
        <EditFormSettings UserControlName="~/includes/userControls/MenuForm.ascx" EditFormType="WebUserControl">
            <EditColumn UniqueName="MenuForm">
            </EditColumn>
        </EditFormSettings>
        <SelfHierarchySettings KeyName="MenuID" ParentKeyName="ParentID" />
    </MasterTableView>
    <ClientSettings AllowRowsDragDrop="true">
        <Selecting AllowRowSelect="true" />
        <ClientEvents OnRowDropping="gridRowDropping" />
    </ClientSettings>
</telerik:RadGrid>

here's my code behind:

private string[] MenuID = { "MenuID", "ParentID", "SortOrder" };
private List<SiteMenu> MenuList = new List<SiteMenu>();
 
protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    SiteMenuGrid.Skin = "Default";
    SiteMenuGrid.AutoGenerateColumns = false;
    SiteMenuGrid.NeedDataSource += SiteMenuGrid_NeedDataSource;
    SiteMenuGrid.InsertCommand += SiteMenuGrid_InsertCommand;
    SiteMenuGrid.UpdateCommand += SiteMenuGrid_UpdateCommand;
    SiteMenuGrid.DeleteCommand += SiteMenuGrid_DeleteCommand;
    SiteMenuGrid.ItemDataBound += SiteMenuGrid_ItemDataBound;
    SiteMenuGrid.MasterTableView.CommandItemDisplay = GridCommandItemDisplay.Top;
    SiteMenuGrid.MasterTableView.CommandItemSettings.ShowRefreshButton = false;
    SiteMenuGrid.ClientSettings.AllowRowsDragDrop = true;
    SiteMenuGrid.ClientSettings.Selecting.AllowRowSelect = true;
    SiteMenuGrid.ClientSettings.ClientEvents.OnRowDropping = "gridRowDropping";
 
    MenuList = new SiteMenu().SelectAllPublicMenuItemsBySiteIDNotDeleted(PCSSession.Current.SiteID);
}
 
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (!IsPostBack)
    {
        SiteMenuGrid.MasterTableView.FilterExpression = "ParentID = 0";
    }
}
 
protected void SiteMenuGrid_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
    SiteMenuGrid.DataSource = MenuList;
}
 
protected void SiteMenuGrid_ItemCreated(object sender, GridItemEventArgs e)
{
    if (e.Item is GridNoRecordsItem && e.Item.OwnerTableView != e.Item.OwnerTableView.OwnerGrid.MasterTableView)
    {
        e.Item.OwnerTableView.ParentItem.Expanded = false;
        e.Item.OwnerTableView.ParentItem["ExpandColumn"].Controls[0].Visible = false;
    }
    if (e.Item is GridCommandItem && e.Item.OwnerTableView != SiteMenuGrid.MasterTableView)
    {
        e.Item.Style["display"] = "none";
    }
}
 
protected void SiteMenuGrid_ItemDataBound(object sender, GridItemEventArgs e)
{

}
 
protected void SiteMenuGrid_InsertCommand(object sender, GridCommandEventArgs e)
{

}
 
protected void SiteMenuGrid_UpdateCommand(object sender, GridCommandEventArgs e)
{
}
 
protected void SiteMenuGrid_DeleteCommand(object sender, GridCommandEventArgs e)
{

}
 
protected void SiteMenuGrid_RowDrop(object sender, GridDragDropEventArgs e)
{
    int key = (int)e.DraggedItems[0].GetDataKeyValue("MenuID");
 
    int destinationId = 0;
    int sortOrder = 0;
 
    if (IsUnder.Checked)
    {
        destinationId = (int)e.DestDataItem.GetDataKeyValue("MenuID");
        sortOrder = 1;
    }
    else
    {
        destinationId = (int)e.DestDataItem.GetDataKeyValue("ParentID");
        sortOrder = ((int)e.DestDataItem.GetDataKeyValue("SortOrder")) + 1;
    }
 
    if (destinationId == 0)
    {
        if (key != destinationId)
        {
            MenuList.FirstOrDefault(i => i.MenuID == key).ParentID = destinationId;
            MenuList.FirstOrDefault(i => i.MenuID == key).SortOrder = sortOrder;
 
            foreach (SiteMenu menuItem in MenuList.Where(i => i.ParentID == destinationId))
            {
                if (menuItem.SortOrder >= sortOrder && menuItem.MenuID != key)
                {
                    menuItem.SortOrder += 1;
                }
            }
 
            if (new SiteMenu().UpdateMenuListByParentID(destinationId, MenuList.Where(i => i.ParentID == destinationId).ToList()))
            {
                Response.Redirect("/admin/menuManager/");
            }
        }
    }
    else
    {
        if (key != destinationId && key != MenuList.FirstOrDefault(i => i.MenuID == destinationId).ParentID)
        {
            MenuList.FirstOrDefault(i => i.MenuID == key).ParentID = destinationId;
            MenuList.FirstOrDefault(i => i.MenuID == key).SortOrder = sortOrder;
 
            foreach (SiteMenu menuItem in MenuList.Where(i => i.ParentID == destinationId))
            {
                if (menuItem.SortOrder >= sortOrder && menuItem.MenuID != key)
                {
                    menuItem.SortOrder += 1;
                }
            }
 
            if (new SiteMenu().UpdateMenuListByParentID(destinationId, MenuList.Where(i => i.ParentID == destinationId).ToList()))
            {
                Response.Redirect("/admin/menuManager/");
            }
        }
    }
}

4 Answers, 1 is accepted

Sort by
0
Accepted
Tsvetina
Telerik team
answered on 19 Sep 2012, 03:41 PM
Hi Kevin,

I would advise you to try with a RadTreeList control which is specifically dedicated to working with self-referencing data and has support for items drag and drop. You can see a demo here:
TreeList / Drag-and-drop

Also, some documentation resources that could prove helpful:
Items Drag and Drop
Client-side Events

All the best,
Tsvetina
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Kevin
Top achievements
Rank 1
answered on 20 Sep 2012, 04:44 AM
Thanks.  That fixed the majority of the problems.  The only problem I am having now is that I can't insert from the root level.
0
Tsvetina
Telerik team
answered on 24 Sep 2012, 12:32 PM
Hi Kevin,

Do you still encounter the insert issue? If so, you could paste your RadTreeList declaration and related code behind, so we can check for any visible mistakes in the logic.

Greetings,
Tsvetina
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Kevin
Top achievements
Rank 1
answered on 24 Sep 2012, 02:42 PM
yeah I am still having a problem with the insert at the root level.  When I debug it never even hits the method for handling the inserts.  If you want I can post the info but I moved the post to the forum for tree lists as I thought it was more appropriate since I changed the control.  Here's the link: Tree List Root Level Insert
Tags
Grid
Asked by
Kevin
Top achievements
Rank 1
Answers by
Tsvetina
Telerik team
Kevin
Top achievements
Rank 1
Share this question
or