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

binding to controls in a grid at runtime

3 Answers 128 Views
Grid
This is a migrated thread and some comments may be shown as answers.
CP
Top achievements
Rank 1
Iron
CP asked on 29 Jan 2020, 03:05 PM

Hi,

 

I'm working on a project that takes data in JSON format from both an internal and a 3rd party service and uses the internal data as source for a grid. This grid will eventually allow mapping of data fields between to other applications. The grid has 2 columns, field name in application #1 and mapped field in application #2. If the user clicks insert or edit, the cell in column 1 should become a dropdownlist populated with valid fields from application #1 and the cell in column 2 should become a dropdowntree of data from application #2. Because the source is JSON I'm taking the data in and converting it to a dataset that both controls will understand. This is working and I have 2 valid datasets. The main data for the grid comes from an internal service, again JSON, which contains the currently mapped data for application #1 vs application #2. This data contains key values for the data in the DropDownList and the DropDownTree.

My problem is that all of the examples of this i've found so far use a simple SQL datasource for the controls whereas my data is built at runtime and I cant get the controls to fire when clicking the e.g.edit button because the controls have no data.

Can anyone point me in the right direction please ??

I have a small sample page but not sure if/how i can upload it ?

3 Answers, 1 is accepted

Sort by
0
CP
Top achievements
Rank 1
Iron
answered on 29 Jan 2020, 03:12 PM
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="ComboAndTreeInGrid.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link rel="stylesheet" href="styles.css" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
        <div>

            <telerik:RadScriptManager ID="RadScriptManager1" runat="server" />

            <telerik:RadAjaxManager runat="server" ID="RadAjaxManager1">
                <AjaxSettings>
                    <telerik:AjaxSetting AjaxControlID="RadGrid1">
                        <UpdatedControls>
                            <telerik:AjaxUpdatedControl ControlID="RadGrid1"></telerik:AjaxUpdatedControl>
                        </UpdatedControls>
                    </telerik:AjaxSetting>
                </AjaxSettings>
            </telerik:RadAjaxManager>

            <telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" />

            <telerik:RadAjaxPanel ID="RadAjaxPanel2" runat="server" LoadingPanelID="RadAjaxLoadingPanel1">

                <telerik:RadGrid RenderMode="Lightweight" ID="RadGrid1" GridLines="None" AutoGenerateColumns="false" PageSize="10"
                    AllowPaging="true" AllowSorting="true" runat="server" OnItemDataBound="RadGrid1_ItemDataBound" OnNeedDataSource="RadGrid1_NeedDataSource"
                    AllowAutomaticUpdates="true" AllowAutomaticInserts="true"
                    ShowStatusBar="true" OnItemCreated="RadGrid1_ItemCreated" OnPreRender="RadGrid1_PreRender"
                     OnItemInserted="RadGrid1_ItemInserted" OnItemUpdated="RadGrid1_ItemUpdated">

                    <MasterTableView ShowFooter="false" DataKeyNames="MappingId" EditMode="InPlace" CommandItemDisplay="TopAndBottom">

                        <Columns>

                            <telerik:GridTemplateColumn HeaderText="Max UDF" ItemStyle-Width="240px">
                                <FooterTemplate>Template footer</FooterTemplate>
                                <FooterStyle VerticalAlign="Middle" HorizontalAlign="Center" />
                                <ItemTemplate>
                                    <%#DataBinder.Eval(Container.DataItem, "MaxName")%>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <telerik:RadDropDownTree RenderMode="Lightweight" runat="server" ID="RadDropDownTree1"
                                        DataTextField="Description" DataFieldID="MaxKey" DataFieldParentID="ParentNo" DataValueField="MaxKey"
                                        DefaultMessage="Choose a UDF" SelectedValue='<%#Bind("MaxKey") %>'
                                         ExpandNodeOnSingleClick="true">
                                        <DropDownSettings OpenDropDownOnLoad="false" CloseDropDownOnSelection="true" />
                                    </telerik:RadDropDownTree>
                                </EditItemTemplate>
                            </telerik:GridTemplateColumn>

                            <telerik:GridTemplateColumn HeaderText="FormStack" ItemStyle-Width="240px">
                                <ItemTemplate>
                                    <%#DataBinder.Eval(Container.DataItem, "FormStackName")%>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <telerik:RadComboBox RenderMode="Lightweight" runat="server" ID="RadComboBox1" DataTextField="FormStackName" OnItemsRequested="RadComboBox1_ItemsRequested" EnableLoadOnDemand="true"
                                         DataValueField="FormStackID" SelectedValue='<%#Bind("FormStackID") %>'>
                                    </telerik:RadComboBox>
                                </EditItemTemplate>
                            </telerik:GridTemplateColumn>




                            <telerik:GridEditCommandColumn FooterText="EditCommand footer" UniqueName="EditCommandColumn"
                                HeaderText="Edit" HeaderStyle-Width="100px" UpdateText="Update">
                            </telerik:GridEditCommandColumn>

                            <telerik:GridEditCommandColumn FooterText="DeleteCommand footer" UniqueName="DeleteCommandColumn"
                                HeaderText="Delete" HeaderStyle-Width="100px" UpdateText="Delete">
                            </telerik:GridEditCommandColumn>
                        </Columns>

                    </MasterTableView>

                </telerik:RadGrid>

            </telerik:RadAjaxPanel>

        </div>
    </form>
</body>
</html>
0
CP
Top achievements
Rank 1
Iron
answered on 29 Jan 2020, 03:12 PM
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;

namespace ComboAndTreeInGrid
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        int iUniqueNumber = 0;
        DataTable tblDefinitions = new DataTable();
        DataTable tblFormfields = new DataTable();

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // get the data for the mapping edit fields
                tblDefinitions = GetTreeDataSet();
                tblFormfields = GetFormFieldDataSet();
            }
        }

        private DataTable GetFormFieldDataSet()
        {
            DataTable tblflds = new DataTable("FormStackData");
            tblflds.Columns.Add("FormStackID", typeof(int));
            tblflds.Columns.Add("FormStackName", typeof(string));

            // simulate data returned by the API
            JArray jaFields = JArray.Parse(@"[
                { 'id': '87035776', 'label': 'AgreeToTerms' },
                { 'id': '87040932', 'label': 'Select all that apply:' },
                { 'id': '87073675', 'label': 'What difficulties' },
                { 'id': '87073682', 'label': 'Describe your specific learning difficulty' },
                { 'id': '87073751', 'label': 'Previous Support' },
                { 'id': '87073898', 'label': 'Support type' },
                { 'id': '87073948', 'label': 'Describe the support you have received:' },
                { 'id': '87073796', 'label': 'Support required' },
                { 'id': '87074115', 'label': 'other support' },
                { 'id': '87074116', 'label': 'Describe the support you think you may require' },
                { 'id': '87077199', 'label': 'Why Ask' }
                ]");

            // convert it into a dataset that can be used to populate a RadComboBox
            foreach (JObject joField in jaFields)
            {
                DataRow dr = tblflds.NewRow();
                dr["FormStackID"] = joField["id"];
                dr["FormStackName"] = joField["label"];
                tblflds.Rows.Add(dr);
            }

            return tblflds;
        }

        List<JToken> maxlist = new List<JToken>();
        private DataTable GetTreeDataSet()
        {
            DataTable tbldefs = new DataTable();

            tbldefs = new DataTable();
            tbldefs.Columns.Add("UniqueNo", typeof(string));
            tbldefs.Columns.Add("ParentNo", typeof(string));
            tbldefs.Columns.Add("MaxKey", typeof(string));
            tbldefs.Columns.Add("MaxName", typeof(string));

            // simulate data returned by the API
            maxlist = JArray.Parse(@"[
                { 'Key': 'VWRmU2V0dXAJNDkx', 'Type': 'Folder', 'Name': 'MaxP45', 'ParentFolderKey': 'VWRmU2V0dXAJMA==', 'SortValue': '001431655766' },
                { 'Key': 'Udf/$TYPEID(915)', 'Type': 'EnumField<StringItem>', 'Name': 'Dotmailer Account', 'ParentFolderKey': 'VWRmU2V0dXAJNDY5', 'SortValue': '001431655766' },
                { 'Key': 'VWRmU2V0dXAJNDY5', 'Type': 'Folder', 'Name': 'Dotmailer Integration', 'ParentFolderKey': 'VWRmU2V0dXAJMA==', 'SortValue': '001431677611' },
                { 'Key': 'Udf/$TYPEID(473)', 'Type': 'EnumField<StringItem>', 'Name': 'Permission To Email', 'ParentFolderKey': 'VWRmU2V0dXAJNDY5', 'SortValue': '001431677611' },
                { 'Key': 'Udf/$TYPEID(912)', 'Type': 'EnumField<StringItem>', 'Name': 'Permissions Test', 'ParentFolderKey': 'VWRmU2V0dXAJNDkx', 'SortValue': '001431677611' },
                { 'Key': 'Udf/$TYPEID(258)', 'Type': 'StringField', 'Name': 'QB Customer Name', 'ParentFolderKey': 'VWRmU2V0dXAJMA==', 'SortValue': '001431699456' },
                { 'Key': 'Udf/$TYPEID(429)', 'Type': 'EnumField<StringItem>', 'Name': 'Dotmailer Status', 'ParentFolderKey': 'VWRmU2V0dXAJNDY5', 'SortValue': '001431699456' },
                { 'Key': 'Udf/$TYPEID(907)', 'Type': 'EnumField<StringItem>', 'Name': 'MultiTable', 'ParentFolderKey': 'VWRmU2V0dXAJNDkx', 'SortValue': '001431699456' },
                { 'Key': 'Udf/$TYPEID(520)', 'Type': 'EnumField<StringItem>', 'Name': 'Demerge Preference', 'ParentFolderKey': 'VWRmU2V0dXAJMA==', 'SortValue': '001431721301' },
                { 'Key': 'Udf/$TYPEID(908)', 'Type': 'EnumField<StringItem>', 'Name': 'SingleTable', 'ParentFolderKey': 'VWRmU2V0dXAJNDkx', 'SortValue': '001431721301' },
                { 'Key': 'Udf/$TYPEID(909)', 'Type': 'NumericField', 'Name': 'Number', 'ParentFolderKey': 'VWRmU2V0dXAJNDkx', 'SortValue': '001431743146' },
                { 'Key': 'Udf/$TYPEID(524)', 'Type': 'EnumField<StringItem>', 'Name': 'Delete Company', 'ParentFolderKey': 'VWRmU2V0dXAJMA==', 'SortValue': '001431764991' },
                { 'Key': 'Udf/$TYPEID(910)', 'Type': 'StringField', 'Name': 'Alphabet', 'ParentFolderKey': 'VWRmU2V0dXAJNDkx', 'SortValue': '001431764991' },
                { 'Key': 'Udf/$TYPEID(502)', 'Type': 'DateTimeField', 'Name': 'Date Contact Left', 'ParentFolderKey': 'VWRmU2V0dXAJNDkx', 'SortValue': '001431786836' },
                { 'Key': 'Udf/$TYPEID(911)', 'Type': 'EnumField<StringItem>', 'Name': 'P45YesNo', 'ParentFolderKey': 'VWRmU2V0dXAJNDkx', 'SortValue': '001431808681' }
                ]").ToList();

            // create a dataset containing the flat data sorted into the correct tree order used by the RadDropDownTree control from the resulting list
            iUniqueNumber = 0;
            FlattenList(tbldefs, "VWRmU2V0dXAJMA==", 0);

            return tbldefs;
        }

        private void FlattenList(DataTable tbldefs, string sParentKey, int iParentFolderNumber)
        {
            foreach (JObject us in SetupListGetChildren(sParentKey))
            {
                iUniqueNumber++;

                DataRow tr = tbldefs.NewRow();
                tr["UniqueNo"] = iUniqueNumber.ToString();
                tr["ParentNo"] = iParentFolderNumber == 0 ? null : iParentFolderNumber.ToString();
                tr["MaxKey"] = us["Key"].ToString();
                tr["MaxName"] = us["Name"].ToString();
                tbldefs.Rows.Add(tr);

                if (us["Type"].ToString().ToLower() == "folder")
                {
                    FlattenList(tbldefs, us["Key"].ToString(), iUniqueNumber);
                }
            }
        }

        private IEnumerable<JToken> SetupListGetChildren(string sParentKey)
        {
            return maxlist.FindAll(x => (string)x["ParentFolderKey"] == sParentKey);
        }

        protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
        {
            if (!IsPostBack)
            {
                //if (e.Item is GridDataItem && e.Item.ItemIndex == 0)
                //{
                //    GridDataItem dataItem = e.Item as GridDataItem;
                //    dataItem.Edit = true;
                //}



                //if (e.Item is GridEditableItem && (e.Item as GridEditableItem).IsInEditMode)
                //{
                //    GridEditableItem editedItem = e.Item as GridEditableItem;
                //    GridEditManager editMan = editedItem.EditManager;

                //    GridDropDownListColumnEditor editor = editMan.GetColumnEditor("RadComboBox1") as GridDropDownListColumnEditor;
                //    //in case you have RadComboBox editor for the GridDropDownColumn (this is the default editor),   
                //    //you will need to use ComboBoxControl below instead of DropDownListControl
                //    //Then you can modify the list control as per your custom conventions
                //    editor.DataSource = new object[] { 1, 2, 3 };
                //    editor.DataBind();

                //    //And so on
                //}

                //if (e.Item is GridDataItem)
                //{
                //    GridDataItem dataItem = e.Item as GridDataItem;

                //    // get the DropDown control in the template column
                //    RadComboBox rcb = dataItem.FindControl("RadComboBox1") as RadComboBox;
                //    rcb.DataSource = tblFormfields;
                //    rcb.DataBind();
                //}

            }
        }

        protected void RadGrid1_PreRender(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //foreach (GridItem item in RadGrid1.MasterTableView.Items)
                //{
                //    if (item is GridEditableItem && item.ItemIndex == 0)
                //    {
                //        GridEditableItem editableItem = item as GridDataItem;
                //        editableItem.Edit = true;
                //    }
                //}
                //RadGrid1.Rebind();
            }

            if (!string.IsNullOrEmpty(gridMessage))
            {
                DisplayMessage(gridMessage);
            }
        }

        protected void RadGrid1_ItemInserted(object sender, GridInsertedEventArgs e)
        {
            if (e.Exception != null)
            {
                e.ExceptionHandled = true;
                SetMessage("Customer cannot be inserted. Reason: " + e.Exception.Message);
            }
        }

        protected void RadGrid1_ItemUpdated(object sender, GridUpdatedEventArgs e)
        {
            if (e.Exception != null)
            {
                e.ExceptionHandled = true;
                SetMessage("Customer cannot be inserted. Reason: " + e.Exception.Message);
            }
        }

        private string gridMessage;

        private void SetMessage(string message)
        {
            gridMessage = message;
        }

        private void DisplayMessage(string text)
        {
            RadGrid1.Controls.Add(new LiteralControl(string.Format("<span style='color:red'>{0}</span>", text)));
        }

        protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
        {
            DataTable gdt = new DataTable();
            RadGrid rg = sender as RadGrid;

            gdt.Columns.Add("MappingID", typeof(string));
            gdt.Columns.Add("FormStackID", typeof(int));
            gdt.Columns.Add("FormStackName", typeof(string));
            gdt.Columns.Add("MaxKey", typeof(string));
            gdt.Columns.Add("MaxName", typeof(string));

            DataRow dr = gdt.NewRow();
            dr[0] = 0;
            dr[1] = 87035776;
            dr[2] = "AgreeToTerms";
            dr[3] = "Udf/$TYPEID(910)";
            dr[4] = "MaxP45\\Alphabet";
            gdt.Rows.Add(dr);

            RadGrid1.DataSource = gdt;
        }

        protected void RadGrid1_ItemCreated(object sender, GridItemEventArgs e)
        {
            if (e.Item is GridEditableItem editItem && e.Item.IsInEditMode)
            {
                // ??????????????
            }

        }

        protected void RadComboBox1_ItemsRequested(object sender, RadComboBoxItemsRequestedEventArgs e)
        {
            RadComboBox comboBox = (RadComboBox)sender;

            // Clear the default Item that has been re-created from ViewState at this point.
            comboBox.Items.Clear();

            foreach (DataRow row in tblFormfields.Rows)
            {
                RadComboBoxItem item = new RadComboBoxItem
                {
                    Text = row["FormStackName"].ToString(),
                    Value = row["FormStackID"].ToString()
                };

                comboBox.Items.Add(item);
                item.DataBind();
            }
        }
    }
}
0
Vessy
Telerik team
answered on 03 Feb 2020, 01:07 PM

Hello,

I have just answered your support ticket on the matter, for convenience I will copy my answer here as well:

The faced behavior is caused due to the set to the Combobox SelectedValue. As the control is bound on demand and the items are populated in the ItemsRequested event handler, setting a selected value which is part of the data source cannot be found when the control is initially loaded (hence the thrown error).

A possible approach you can use is to set the Text value (instead of the SelectedValue) in the RadCombobox's PreRender event. Make sure that the CategoryName filed is added to the Grid.MasterTableView.DataKeyNames collection:

            <telerik:RadGrid RenderMode="Lightweight" ID="RadGrid1" runat="server" GridLines="None"
                AutoGenerateColumns="false" PageSize="10" AllowPaging="true" AllowSorting="true" ShowStatusBar="true"
                OnNeedDataSource="RadGrid1_NeedDataSource" OnItemDataBound="RadGrid1_ItemDataBound" OnPreRender="RadGrid1_PreRender"
                OnInsertCommand="RadGrid1_InsertCommand" OnUpdateCommand="RadGrid1_UpdateCommand" OnDeleteCommand="RadGrid1_DeleteCommand">
                <MasterTableView ShowFooter="false" DataKeyNames="ProductID, CategoryName" EditMode="InPlace" CommandItemDisplay="Top" InsertItemPageIndexAction="ShowItemOnCurrentPage">
                    ...
                            <EditItemTemplate>
                                <telerik:RadComboBox RenderMode="Lightweight" runat="server" ID="rcbCategory" DataTextField="CategoryName"
                                    EnableLoadOnDemand="true" OnItemsRequested="RcbCategory_ItemsRequested"
                                    DataValueField="CategoryID" OnSelectedIndexChanged="RcbCategory_SelectedIndexChanged"
                                    OnPreRender="rcbCategory_PreRender">
                                </telerik:RadComboBox>
                            ...
        protected void rcbCategory_PreRender(object sender, EventArgs e)
        {
            RadComboBox combo = (sender as RadComboBox);

            GridDataItem item = combo.NamingContainer as GridDataItem;
            string value = item.GetDataKeyValue("CategoryName").ToString();
            combo.Text = value;
        }

 

Regards,
Vessy
Progress Telerik

Get quickly onboarded and successful with UI for ASP.NET AJAX with the Virtual Classroom technical trainings, available to all active customers. Learn More.
Tags
Grid
Asked by
CP
Top achievements
Rank 1
Iron
Answers by
CP
Top achievements
Rank 1
Iron
Vessy
Telerik team
Share this question
or