+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Drag and drop with RadGrid in the designer of a custom user control results in an error

Drag and drop with RadGrid in the designer of a custom user control results in an error

4 posts, 0 answered
  1. David van Geel
    David van Geel avatar
    59 posts
    Registered:
    19 Aug 2009
    16 Nov 2010
    Link to this post
    Hi,

    The error is an "Object reference not set to an instance of an object". The actual page displays the following (in Dutch).

    Serverfout in toepassing /.
    --------------------------------------------------------------------------------
      
    De objectverwijzing is niet op een exemplaar van een object ingesteld. 
    Beschrijving: Er is een onverwerkte uitzondering opgetreden tijdens het uitvoeren van de huidige webaanvraag. Raadpleeg de stacktracering voor meer informatie over deze fout en de oorsprong ervan in de code. 
      
    Details van uitzondering: System.NullReferenceException: De objectverwijzing is niet op een exemplaar van een object ingesteld.
      
    Fout in bron: 
      
    Er is een onverwerkte uitzondering gegenereerd tijdens het uitvoeren van de huidige webaanvraag. Aan de hand van de onderstaande tracering van de uitzonderingsstack kunt u meer informatie verkrijgen over de oorsprong en de locatie van de uitzondering.  
      
    Stacktracering: 
      
      
    [NullReferenceException: De objectverwijzing is niet op een exemplaar van een object ingesteld.]
       Telerik.Web.UI.RadGrid.RaisePostBackEvent(String eventArgument) +8023
       System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
       System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +175
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565
      
       
    --------------------------------------------------------------------------------
    Versiegegevens: Microsoft .NET Framework Versie:2.0.50727.4206; ASP.NET Versie:2.0.50727.4209

    The code of the designer is defined as follows.
    using System;
    using System.Collections;
    using System.Web.UI;
    using System.Collections.Generic;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    using Telerik.Framework.Web;
    using Telerik.Cms.Web.UI;
    using Telerik.Web.UI;
      
    /// <summary>
    /// Summary description for TickertapeDesigner
    /// </summary>
    public class TickertapeDesigner : Telerik.Framework.Web.Design.ControlDesigner
    {
        #region Public Properties
      
        /// <summary>
        /// Gets or sets the template used by LinksListDesigner control
        /// </summary>
        public ITemplate LayoutTemplate
        {
            get
            {
                return layoutTemplate;
            }
            set
            {
                layoutTemplate = value;
            }
        }
      
        /// <summary>
        /// Gets or sets the path of the template used by LinksListDesigner control
        /// </summary>
        public virtual string LayoutTemplatePath
        {
            get
            {
                if (ViewState["LayoutTemplatePath"] == null)
                    return "~/Estate/UserControls/Designers/TickertapeDesigner.ascx";
                return ViewState["LayoutTemplatePath"] as string;
            }
            set
            {
                ViewState["LayoutTemplatePath"] = value;
            }
        }
      
        #endregion
      
        #region Base Overrides
      
        /// <summary>
        /// Restores control state information from a previous page request that was saved by the SaveControlState
        /// method.
        /// </summary>
        /// <param name="savedState">Represents the control state to be restored.</param>
        /// <remarks>Notice that this method loads the state from the base class as well</remarks>
        protected override void LoadControlState(object savedState)
        {
            if (savedState != null)
            {
                object[] state = (object[])savedState;
                base.LoadControlState(state[0]);
                temporaryLinksList = (List<TickerItem>)state[1];
            }
        }
      
        /// <summary>
        /// Saves server control state changes.
        /// </summary>
        /// <returns>Array of objects to be saved with the control state</returns>
        /// <remarks>Notice that this method saves the state for the base class as well</remarks>
        protected override object SaveControlState()
        {
            return new object[] { 
                    base.SaveControlState(),
                    temporaryLinksList
                };
        }
      
        /// <summary>
        /// Renders the HTML opening tag of the control to the specified writer. This method is used primarily by control developers.
        /// </summary>
        /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that represents the output stream to render HTML content on the client.</param>
        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            //Do not render
        }
      
        /// <summary>
        /// Renders the HTML closing tag of the control into the specified writer. This method is used primarily by control developers.
        /// </summary>
        /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that represents the output stream to render HTML content on the client.</param>
        public override void RenderEndTag(HtmlTextWriter writer)
        {
            //Do not render
        }
      
        /// <summary>
        /// Creates the child controls in LinksListDesigner control.
        /// </summary>
        protected override void CreateChildControls()
        {
            Controls.Clear();
      
            InitializeTemplate();
            InitializeComponent();
      
            container.LinksGrid.MasterTableView.DataKeyNames = new string[] { "Id" };
            container.LinksGrid.DeleteCommand += new GridCommandEventHandler(LinksGrid_DeleteCommand);
            container.LinksGrid.EditCommand += new GridCommandEventHandler(LinksGrid_EditCommand);
            container.LinksGrid.CancelCommand += new GridCommandEventHandler(LinksGrid_CancelCommand);
            container.LinksGrid.UpdateCommand += new GridCommandEventHandler(LinksGrid_UpdateCommand);
            container.LinksGrid.InsertCommand += new GridCommandEventHandler(LinksGrid_InsertCommand);
            container.LinksGrid.NeedDataSource += new GridNeedDataSourceEventHandler(LinksGrid_NeedDataSource);
            container.LinksGrid.RowDrop += new GridDragDropEventHandler(LinksGrid_RowDrop);
      
            Controls.Add(container);
        }
      
        #endregion
      
        #region Protected Virtual Methods
      
        /// <summary>
        /// Initializes the template to use. The principle is very similar to how we do it in all the controls
        /// </summary>
        protected virtual void InitializeTemplate()
        {
            container = new TickertapeDesignerContainer(this);
            layoutTemplate = ControlUtils.GetTemplate<DefaultMyBulletedListDesignerTemplate>(LayoutTemplatePath);
            layoutTemplate.InstantiateIn(container);
        }
      
        /// <summary>
        /// Initializes the component which is our public control.
        /// </summary>
        /// <remarks>
        /// By "component" we understand the control for which designer is setting properties. By having a 
        /// reference to the "component" we can access or modify the properties of that control / component.
        /// </remarks>
        protected virtual void InitializeComponent()
        {
            if (DesignedControl != null)
            {
                component = (TickertapeControlBase)DesignedControl;
                properties = TypeDescriptor.GetProperties(component);
            }
        }
      
        #endregion
      
        #region Private methods
      
        private void BindGrid()
        {
            container.LinksGrid.DataSource = temporaryLinksList;
            container.LinksGrid.DataBind();
        }
      
        private void UpdateLinksList()
        {
            component.ListLinks = temporaryLinksList;
            base.OnPropertyChanged(EventArgs.Empty);
        }
      
        #endregion
      
        #region Event Handlers
      
        private void LinksGrid_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
        {
            if (temporaryLinksList == null)
                temporaryLinksList = component.ListLinks;
            container.LinksGrid.DataSource = temporaryLinksList;
        }
      
        private void LinksGrid_InsertCommand(object source, GridCommandEventArgs e)
        {
            GridEditableItem editedItem = e.Item as GridEditableItem;
            UserControl userControl = (UserControl)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
            Hashtable newValues = new Hashtable();
            newValues["Title"] = (userControl.FindControl("txtItemTitle") as TextBox).Text;
            newValues["Summary"] = (userControl.FindControl("txtItemSummary") as TextBox).Text;
            newValues["Url"] = (userControl.FindControl("txtItemUrl") as TextBox).Text;
      
            temporaryLinksList.Add(new TickerItem(temporaryLinksList.Count + 1, newValues["Title"].ToString(), newValues["Summary"].ToString(), newValues["Url"].ToString()));
            UpdateLinksList();
            BindGrid();
        }
      
        private void LinksGrid_DeleteCommand(object source, GridCommandEventArgs e)
        {
            int id = int.Parse((e.Item as GridDataItem).OwnerTableView.DataKeyValues[e.Item.ItemIndex]["Id"].ToString());
            if (temporaryLinksList.Exists(i => i.Id == id))
            {
                temporaryLinksList.Remove(temporaryLinksList.Find(i => i.Id == id));
            }
            UpdateLinksList();
            BindGrid();
        }
      
        private void LinksGrid_EditCommand(object source, GridCommandEventArgs e)
        {
            e.Item.OwnerTableView.Items[e.Item.ItemIndex].Edit = true;
            BindGrid();
        }
      
        private void LinksGrid_CancelCommand(object source, GridCommandEventArgs e)
        {
            if (e.Item.ItemIndex > 0 && e.Item.OwnerTableView.Items[e.Item.ItemIndex].IsInEditMode)
                e.Item.OwnerTableView.Items[e.Item.ItemIndex].Edit = false;
            BindGrid();
        }
      
        private void LinksGrid_UpdateCommand(object source, GridCommandEventArgs e)
        {
            GridEditableItem editedItem = e.Item as GridEditableItem;
            UserControl userControl = (UserControl)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
            Hashtable newValues = new Hashtable();
            newValues["Id"] = (userControl.FindControl("txtItemId") as TextBox).Text;
            newValues["Title"] = (userControl.FindControl("txtItemTitle") as TextBox).Text;
            newValues["Summary"] = (userControl.FindControl("txtItemSummary") as TextBox).Text;
            newValues["Url"] = (userControl.FindControl("txtItemUrl") as TextBox).Text;
            int id = int.Parse(newValues["Id"].ToString());
              
            List<TickerItem> updatedListLinks = new List<TickerItem>();
            foreach (TickerItem link in temporaryLinksList)
            {
                if (link.Id == id)
                {
                    updatedListLinks.Add(new TickerItem(int.Parse(newValues["Id"].ToString()), newValues["Title"].ToString(), newValues["Summary"].ToString(), newValues["Url"].ToString()));
                }
                else
                {
                    updatedListLinks.Add(new TickerItem(link.Id, link.Title, link.Summary, link.Url));
                }
            }
            temporaryLinksList = updatedListLinks;
            UpdateLinksList();
            BindGrid();
        }
          
        private void LinksGrid_RowDrop(object sender, GridDragDropEventArgs e)
        {
            if (e.DestDataItem != null && e.DestDataItem.OwnerGridID == container.LinksGrid.ClientID)
            {
                //reorder items in grid
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                int destinationIndex = 123;
      
                if (e.DropPosition == GridItemDropPosition.Above && e.DestDataItem.ItemIndex > e.DraggedItems[0].ItemIndex)
                {
                    destinationIndex -= 1;
                }
                if (e.DropPosition == GridItemDropPosition.Below && e.DestDataItem.ItemIndex < e.DraggedItems[0].ItemIndex)
                {
                    destinationIndex += 1;
                }
      
            }
        }
      
        #endregion
      
        #region Protected Fields
      
        /// <summary>
        /// Gets or sets the myBulletedList designer container.
        /// </summary>
        /// <value>The myBulletedList designer container.</value>
        protected TickertapeDesignerContainer Container
        {
            get
            {
                return container;
            }
            set
            {
                container = value;
            }
        }
      
        /// <summary>
        /// Gets or sets the component which is of TickertapeControlBase type.
        /// </summary>
        /// <value>The component which is of TickertapeControlBase type.</value>
        protected TickertapeControlBase Component
        {
            get
            {
                return component;
            }
            set
            {
                component = value;
            }
        }
      
        #endregion
      
        #region Private Fields
      
        private ITemplate layoutTemplate;
        private TickertapeDesignerContainer container;
        private TickertapeControlBase component;
        private PropertyDescriptorCollection properties;
        private List<TickerItem> temporaryLinksList;
      
        #endregion
      
        #region Default Template
      
        /// <summary>
        /// Default template for the LinksListDesigner control designer. NOT IMPLEMENTED!
        /// </summary>
        protected class DefaultMyBulletedListDesignerTemplate : ITemplate
        {
            /// <summary>
            /// When implemented by a class, defines the object that child controls and templates belong to. 
            /// These child controls are in turn defined within an inline template.
            /// </summary>
            /// <param name="container">The object to contain the instances of controls from the inline template.</param>
            public void InstantiateIn(Control container)
            {
                throw new NotImplementedException("Default control designer not implemented!");
            }
        }
      
        #endregion
      
        #region Container
      
        /// <summary>
        /// The container class for the LinksListDesigner control designer.
        /// </summary>
        protected class TickertapeDesignerContainer : GenericContainer<TickertapeDesigner>
        {
            /// <summary>
            /// Initializes a new instance of the LinksListDesignerContainer class.
            /// </summary>
            /// <param name="owner">The LinksListDesigner control.</param>
            public TickertapeDesignerContainer(TickertapeDesigner owner)
                : base(owner, true)
            {
            }
      
            public RadGrid LinksGrid
            {
                get
                {
                    if (linksGrid == null)
                        linksGrid = FindRequiredControl<RadGrid>("linksGrid");
                    return linksGrid;
                }
            }
      
            private RadGrid linksGrid;
        }
      
        #endregion
    }

    The template of the designer is defined as follows:
    <%@ control language="C#" %>
    <%@ register tagprefix="sfLib" namespace="Telerik.Libraries.WebControls" assembly="Telerik.Libraries" %>
    <telerik:cssfilelink id="CssFileLink" filename="~/Estate/css/controldesigner.css" media="screen" runat="server" />
      
    <div class="ctrlProps celDesigner">
        <div class="ctrlContent">
            <h3>
                <asp:literal runat="server" text="<%$Resources:Title %>" />
            </h3>
            <p>
                <asp:literal runat="server" text="<%$Resources:pIntro %>" /></p>
            <ul>
                <li>
                    <asp:label id="Label1" runat="server" text="<%$Resources:lblTitle %>" cssclass="label" />
                    <asp:textbox id="txtTitle" runat="server" />
                </li>
            </ul>
            <h3>
                <asp:literal runat="server" text="<%$Resources:lblItemsList %>" />
            </h3>
              
            <telerik:radgrid id="linksGrid" runat="server" autogeneratecolumns="False" gridlines="None" skin="Default" allowmultirowselection="false">
                <mastertableview commanditemdisplay="Top">
                    <commanditemsettings addnewrecordtext="<%$Resources:InsertItem %>" />
                    <rowindicatorcolumn visible="False">
                        <headerstyle width="20px"></headerstyle>
                    </rowindicatorcolumn>
                    <expandcollapsecolumn visible="False" resizable="False">
                        <headerstyle width="20px"></headerstyle>
                    </expandcollapsecolumn>
                    <columns>
                        <telerik:gridboundcolumn datafield="Id" headertext="Id" uniquename="Id" visible="false">
                        </telerik:gridboundcolumn>
                        <telerik:gridboundcolumn datafield="Title" headertext="<%$Resources:lblItemTitle %>" uniquename="Title">
                        </telerik:gridboundcolumn>
                        <telerik:gridboundcolumn datafield="Summary" headertext="<%$Resources:lblItemSummary %>" uniquename="Summary">
                        </telerik:gridboundcolumn>
                        <telerik:gridboundcolumn datafield="Url" headertext="<%$Resources:lblItemUrl %>" uniquename="Url">
                        </telerik:gridboundcolumn>
                        <telerik:gridbuttoncolumn commandname="Delete" text="<%$Resources:Delete %>" uniquename="Delete" confirmtext="<%$Resources:ConfirmDelete %>">
                        </telerik:gridbuttoncolumn>
                        <telerik:gridbuttoncolumn commandname="Edit" text="<%$Resources:Edit %>" uniquename="Edit">
                        </telerik:gridbuttoncolumn>
                    </columns>
                    <editformsettings usercontrolname="~/Estate/Usercontrols/Designers/TickerItemDetails.ascx" editformtype="WebUserControl">
                        <editcolumn uniquename="EditCommandColumn1" />
                    </editformsettings>
                </mastertableview>
                <clientsettings allowrowsdragdrop="True">
                    <selecting allowrowselect="True"/>
                </clientsettings>
            </telerik:radgrid>
        </div>
    </div>

    The edit, delete and update commands work just fine. Only the rowdrop event isn't executed. Note that this code is -for the most part- based on the LinksList examples from the documentation.

    Any information would be appreciated,

    Regards,

    David
  2. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    22 Nov 2010
    Link to this post
    Hello David van Geel,

    Thank you for submitting your code in a support request..

    I have responded in the request, however will post my response here too.

    We have been trying to fix the issue as it is not caused by your code. The problem lies in the page/control life cycle of the control editors. We have tried to resolve the issue in the control base classes however were unable to. Unfortunately you would have to take another approach for letting users define the ordering of items in the grid - add an index value and sort them in the NeedDataSource event of the grid and OnSaving.

    Best wishes,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. David van Geel
    David van Geel avatar
    59 posts
    Registered:
    19 Aug 2009
    22 Nov 2010
    Link to this post
    Hi,

    In the end I solved this by adding a "up" and "down" button column to the grid, adding an event handler to the ItemCommand event and adding some code to disable the "Up" column for the first row and disable the "down" column for the last row.

    Take a look at the following code if you are interested.

    Regards,


    David

    <telerik:radgrid id="linksGrid" runat="server" autogeneratecolumns="False" gridlines="None" skin="Default" allowmultirowselection="false">
        <mastertableview commanditemdisplay="Top">
            <commanditemsettings addnewrecordtext="<%$Resources:InsertItem %>" />
            <rowindicatorcolumn visible="False">
                <headerstyle width="20px"></headerstyle>
            </rowindicatorcolumn>
            <expandcollapsecolumn visible="False" resizable="False">
                <headerstyle width="20px"></headerstyle>
            </expandcollapsecolumn>
            <columns>
                <telerik:gridbuttoncolumn commandname="Up" text="<%$Resources:Up %>" uniquename="Up" buttontype="LinkButton">
                </telerik:gridbuttoncolumn>
                <telerik:gridbuttoncolumn commandname="Down" text="<%$Resources:Down %>" uniquename="Down" buttontype="LinkButton">
                </telerik:gridbuttoncolumn>
                <telerik:gridboundcolumn datafield="Id" headertext="Id" uniquename="Id" visible="false">
                </telerik:gridboundcolumn>
                <telerik:gridboundcolumn datafield="Title" headertext="<%$Resources:lblItemTitle %>" uniquename="Title">
                </telerik:gridboundcolumn>
                <telerik:gridboundcolumn datafield="Summary" headertext="<%$Resources:lblItemSummary %>" uniquename="Summary">
                </telerik:gridboundcolumn>
                <telerik:gridboundcolumn datafield="Url" headertext="<%$Resources:lblItemUrl %>" uniquename="Url">
                </telerik:gridboundcolumn>
                <telerik:gridbuttoncolumn commandname="Delete" text="<%$Resources:Delete %>" uniquename="Delete" confirmtext="<%$Resources:ConfirmDelete %>">
                </telerik:gridbuttoncolumn>
                <telerik:gridbuttoncolumn commandname="Edit" text="<%$Resources:Edit %>" uniquename="Edit">
                </telerik:gridbuttoncolumn>
            </columns>
            <editformsettings usercontrolname="~/Estate/Usercontrols/Designers/TickerItemDetails.ascx" editformtype="WebUserControl">
                <editcolumn uniquename="EditCommandColumn1" />
            </editformsettings>
        </mastertableview>
        <clientsettings allowrowsdragdrop="True">
            <selecting allowrowselect="True"/>
        </clientsettings>
    </telerik:radgrid>

    protected override void CreateChildControls()
    {
        Controls.Clear();
        InitializeTemplate();
        InitializeComponent();
          
        container.TxtTitle.Text = ((TickertapeControlBase)DesignedControl).ControlTitle;
        container.LinksGrid.MasterTableView.DataKeyNames = new string[] { "Id" };
        container.LinksGrid.DeleteCommand += new GridCommandEventHandler(LinksGrid_DeleteCommand);
        container.LinksGrid.EditCommand += new GridCommandEventHandler(LinksGrid_EditCommand);
        container.LinksGrid.CancelCommand += new GridCommandEventHandler(LinksGrid_CancelCommand);
        container.LinksGrid.UpdateCommand += new GridCommandEventHandler(LinksGrid_UpdateCommand);
        container.LinksGrid.InsertCommand += new GridCommandEventHandler(LinksGrid_InsertCommand);
        container.LinksGrid.NeedDataSource += new GridNeedDataSourceEventHandler(LinksGrid_NeedDataSource);
        container.LinksGrid.ItemCommand += new GridCommandEventHandler(LinksGrid_ItemCommand);
        container.LinksGrid.ItemDataBound += new GridItemEventHandler(LinksGrid_ItemDataBound);
        Controls.Add(container);
    }
     
    protected void LinksGrid_ItemCommand(object source, GridCommandEventArgs e)
    {
        if (e.Item.DataItem != null)
        {
            if (e.CommandName == "Up" || e.CommandName == "Down")
            {
                int id = ((TickerItem)e.Item.DataItem).Id;
                int newid = id + 1;
                if (e.CommandName == "Up")
                {
                    newid = id - 1;
                }
                if (newid >= 0 && newid <= temporaryLinksList.Count - 1)
                
                    List<TickerItem> updatedListLinks = new List<TickerItem>();        
                    for (int i = 0; i < temporaryLinksList.Count; i++)
                    {
                        if (e.CommandName == "Down" && i == id)
                        {
                            updatedListLinks.Add(new TickerItem(i, temporaryLinksList[i + 1].Title, temporaryLinksList[i + 1].Summary, temporaryLinksList[i + 1].Url));
                            updatedListLinks.Add(new TickerItem(i + 1, temporaryLinksList[i].Title, temporaryLinksList[i].Summary, temporaryLinksList[i].Url));
                        }
                        else if (e.CommandName == "Up" && i == id)
                        {
                            updatedListLinks.Add(new TickerItem(i - 1, temporaryLinksList[i].Title, temporaryLinksList[i].Summary, temporaryLinksList[i].Url));
                            updatedListLinks.Add(new TickerItem(i, temporaryLinksList[i - 1].Title, temporaryLinksList[i - 1].Summary, temporaryLinksList[i - 1].Url));
                        }
                        else if (i != newid)
                        {
                            updatedListLinks.Add(new TickerItem(i, temporaryLinksList[i].Title, temporaryLinksList[i].Summary, temporaryLinksList[i].Url));
                        }
                    }
                    temporaryLinksList = updatedListLinks;
                    UpdateLinksList();
                    BindGrid();
                }
            }
        }
    }
      
    protected void LinksGrid_ItemDataBound(object sender, GridItemEventArgs e)
    {
        if (e.Item is GridDataItem)
        {
            GridDataItem dataItem = (GridDataItem)e.Item;
            int id = ((TickerItem)e.Item.DataItem).Id;
            if (id == 0)
            {
                Control btn = (Control)dataItem["Up"].Controls[0];
                btn.Visible = false
            }
            else if (id == temporaryLinksList.Count - 1)
            {
                Control btn = (Control)dataItem["Down"].Controls[0];
                btn.Visible = false
            }
        }
    }
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    09 Dec 2016
    22 Nov 2010
    Link to this post
    Hello David,

    I am happy to see that this works for you and I believe that this will help to the other members that will face the same issue.

    Best wishes,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Register for webinar
4 posts, 0 answered