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

Custom Column Render Problem

5 Answers 72 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Delvis
Top achievements
Rank 1
Delvis asked on 03 Mar 2015, 01:09 AM
I created my own  Template column. Everything works ok. But when I add a child hierarchy and expand any row, the values of that column in the father grid are lost.

Any suggestions on this?

I added part of my code to show the situation.

Code:

public class MyGridTemplateColumn : GridTemplateColumn
{
    public override void Initialize()
    {
        base.Initialize();

        HeaderStyle.Width = Unit.Pixel(105);
        HeaderText = "State";
        UniqueName = "StateCol";

        DataField = "StateId";
        DataType = typeof(byte);

        var _dataSource = new List<KeyValuePair<int, string>>
        {
            new KeyValuePair<int, string>(1, "Active"),
            new KeyValuePair<int, string>(2, "Deleted"),
            new KeyValuePair<int, string>(3, "Inactive"),
            new KeyValuePair<int, string>(6, "Other")
        };

        ItemTemplate = new MyItemTemplate(this.DataField, _dataSource);
        EditItemTemplate = new MyEditItemTemplate(this.DataField, _dataSource);
    }

    public override GridColumn Clone()
    {
        var res = new MyGridTemplateColumn();
        res.CopyBaseProperties(this);

        return res;
    }

    private class MyItemTemplate : ITemplate
    {
        private readonly string _dataField;
        private readonly List<KeyValuePair<int, string>> _dataSource = new List<KeyValuePair<int, string>>();

        public MyItemTemplate(string dataField, List<KeyValuePair<int, string>> origenDatos)
        {
            _dataField = dataField;
            _dataSource = origenDatos;
        }

        public void InstantiateIn(System.Web.UI.Control container)
        {
            var lControl = new LiteralControl { ID = _dataField + "_lControl" };
            lControl.DataBinding += lControl_DataBinding;
            container.Controls.Add(lControl);
        }

        private void lControl_DataBinding(object sender, EventArgs e)
        {
            var l = (LiteralControl)sender;
            var value = l.NamingContainer.GetFieldValue("DataItem." + _dataField);
            if (value != null)
                l.Text = _dataSource.FirstOrDefault(s=>s.Key == (int)value).Value;
        }
    }

    private class MyEditItemTemplate : IBindableTemplate
    {
        private readonly string _dataField;
        private readonly List<KeyValuePair<int, string>> _dataSource = new List<KeyValuePair<int, string>>();

        public MyEditItemTemplate(string dataField, List<KeyValuePair<int, string>> origenDatos)
        {
            _dataField = dataField;
            _dataSource = origenDatos;
        }

        public void InstantiateIn(System.Web.UI.Control container)
        {
            var rcBox = new RadComboBox
            {
                ID = _dataField + "_RadComboBox",
                DataTextField = "Value",
                DataValueField = "Key",
                DataSource = _dataSource
            };

            rcBox.DataBinding += rcBox_DataBinding;
            container.Controls.Add(rcBox);
        }

        public IOrderedDictionary ExtractValues(Control container)
        {
            var dictionary = new OrderedDictionary
            {
                {_dataField, (container.FindControl(_dataField + "_RadComboBox") as RadComboBox).SelectedValue}
            };
            return dictionary;
        }

        private void rcBox_DataBinding(object sender, EventArgs e)
        {
            var rcBox = (RadComboBox)sender;
            var value = rcBox.NamingContainer.GetFieldValue("DataItem." + _dataField);
            rcBox.SelectedValue = value != null ? value.ToString() : string.Empty;
        }
    }

Usage:

<telerik:RadGrid ID="RadGrid1" runat="server" DataSourceID="LinqDataSource1" AllowPaging="True" AutoGenerateColumns="False" Width="50%">
    <MasterTableView DataKeyNames="ENTUserAccountId" DataSourceID="LinqDataSource1" PageSize="5">
        <Columns>
            <telerik:GridBoundColumn DataField="UserName" HeaderText="UserName" UniqueName="UserName"/>
            <telerik:GridBoundColumn DataField="Email" HeaderText="Email" UniqueName="Email"/>
            <a:MyGridTemplateColumn />
        </Columns>
        <DetailTables>
            <telerik:GridTableView runat="server" DataSourceID="LinqDataSource2" DataKeyNames="ENTUserAccountId">
                <ParentTableRelation>
                    <telerik:GridRelationFields DetailKeyField="ENTUserAccountId" MasterKeyField="ENTUserAccountId" />
                </ParentTableRelation>
                <Columns>
                    <telerik:GridTemplateColumn DataField="ENTRoleId" HeaderText="Rol" UniqueName="ENTRoleId">
                        <ItemTemplate>
                            <asp:Label ID="ENTRoleIdLabel" runat="server" Text='<%# Eval("ENTRole.RoleName") %>'></asp:Label>
                        </ItemTemplate>
                    </telerik:GridTemplateColumn>
                </Columns>                 
            </telerik:GridTableView>
        </DetailTables>
    </MasterTableView>
</telerik:RadGrid>

<asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="TelerikWebApp1.DataClasses1DataContext"
    EntityTypeName="" TableName="ENTUserAccount"/>
        
<asp:LinqDataSource ID="LinqDataSource2" runat="server" ContextTypeName="TelerikWebApp1.DataClasses1DataContext"
    EntityTypeName="" TableName="ENTRoleUserAccount" Where="ENTUserAccountId == @ENTUserAccountId">
        <WhereParameters>
            <asp:SessionParameter Name="ENTUserAccountId" Type="Int32" />
        </WhereParameters>
</asp:LinqDataSource>  



5 Answers, 1 is accepted

Sort by
0
Delvis
Top achievements
Rank 1
answered on 03 Mar 2015, 01:33 AM
the image....
0
Kostadin
Telerik team
answered on 05 Mar 2015, 02:54 PM
Hi Delvis,

I assume the reason for not displaying any content in the template is that it is not recreated after a postback. I would suggest you to create the entire grid structure programmatically as demonstrated in the following help article.

Regards,
Kostadin
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Delvis
Top achievements
Rank 1
answered on 06 Mar 2015, 12:12 AM
Hi, Kostadin.

I appreciate your response.

The idea is to use the column in any grid in my application without having to create the grid by code every time you need to use it.

Examining the code I see that when it expands or contracts the child grid, the bind event is not fired (lControl_DataBinding). Any idea how this works in other columns that comes by default in the RadGrid?
0
Delvis
Top achievements
Rank 1
answered on 06 Mar 2015, 06:26 PM
Hi, Kostadin.

Based on the example article that provided me (http://www.telerik.com/help/aspnet-ajax/grid-programmatic-creation.html), I have made an example and when expand or collapse the child grid template column values are lost. What else I can do?

Example code:

ASPX:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GridProg.aspx.cs" Inherits="TelerikWebApp1.GridProg" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <telerik:RadScriptManager ID="RadScriptManager1" runat="server"/>        
        <asp:PlaceHolder ID="PlaceHolder1" runat="server" />
        <asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="TelerikWebApp1.DataClasses1DataContext"
            EntityTypeName="" TableName="ENTUserAccount"/>
        
        <asp:LinqDataSource ID="LinqDataSource2" runat="server" ContextTypeName="TelerikWebApp1.DataClasses1DataContext"
                            EntityTypeName="" TableName="ENTRoleUserAccount"/>
    </div>
    </form>
</body>
</html>

C#:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;

namespace TelerikWebApp1
{
    public partial class GridProg : Page
    {
        private void DefineGridStructure()
        {
            var RadGrid1 = new RadGrid {DataSourceID = "LinqDataSource1"};
            RadGrid1.MasterTableView.DataKeyNames = new[] { "ENTUserAccountId" };
            RadGrid1.Width = Unit.Percentage(50);
            RadGrid1.PageSize = 5;
            RadGrid1.AllowPaging = true;
            RadGrid1.AutoGenerateColumns = false;
            //Add columns
            var boundColumn = new GridBoundColumn {DataField = "UserName", HeaderText = "UserName"};
            RadGrid1.MasterTableView.Columns.Add(boundColumn);

            const string templateColumnName = "State";
            var templateColumn = new GridTemplateColumn
            {
                ItemTemplate = new MyTemplate(templateColumnName),
                HeaderText = templateColumnName
            };
            RadGrid1.MasterTableView.Columns.Add(templateColumn);

            //Detail table - Orders (II in hierarchy level)
            var tableViewOrders = new GridTableView(RadGrid1)
            {
                DataSourceID = "LinqDataSource2",
                DataKeyNames = new[] {"ENTUserAccountId"}
            };
            var relationFields = new GridRelationFields
            {
                MasterKeyField = "ENTUserAccountId",
                DetailKeyField = "ENTUserAccountId"
            };
            tableViewOrders.ParentTableRelation.Add(relationFields);
            RadGrid1.MasterTableView.DetailTables.Add(tableViewOrders);
            //Add columns
            boundColumn = new GridBoundColumn {DataField = "ENTRole.RoleName", HeaderText = "Rol"};
            tableViewOrders.Columns.Add(boundColumn);

            //Add the RadGrid instance to the controls
            PlaceHolder1.Controls.Add(RadGrid1);
        }

        private class MyTemplate : ITemplate
        {
            private LiteralControl lControl;

            private readonly string _colname;
            public MyTemplate(string cName)
            {
                _colname = cName;
            }
            public void InstantiateIn(Control container)
            {
                lControl = new LiteralControl {ID = "lControl"};
                lControl.DataBinding += lControl_DataBinding;
                container.Controls.Add(lControl);
            }

            private void lControl_DataBinding(object sender, EventArgs e)
            {
                var l = (LiteralControl)sender;
                var item = (GridItem)l.NamingContainer;
                var value = DataBinder.Eval(item.DataItem, _colname);
                if (value != null)
                    l.Text = value.ToString();
            }
        }

        protected void Page_Init(object source, System.EventArgs e)
        {
            DefineGridStructure();
        }
    }
}
0
Accepted
Kostadin
Telerik team
answered on 10 Mar 2015, 03:34 PM
Hello Delvis,

The reason is that after a postback the DataBinding event of the Literal control is not fired and in this case you are creating a new LiteralControl without Text. A possible solution is to find the control on ItemDataBound event handler as descried in the following help article and set a text of the Literal control.

Regards,
Kostadin
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
Grid
Asked by
Delvis
Top achievements
Rank 1
Answers by
Delvis
Top achievements
Rank 1
Kostadin
Telerik team
Share this question
or