Custom Column Render Problem

6 posts, 1 answers
  1. Delvis
    Delvis avatar
    18 posts
    Member since:
    Mar 2012

    Posted 02 Mar 2015 Link to this post

    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>  



  2. Delvis
    Delvis avatar
    18 posts
    Member since:
    Mar 2012

    Posted 02 Mar 2015 in reply to Delvis Link to this post

    the image....
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Kostadin
    Admin
    Kostadin avatar
    1711 posts

    Posted 05 Mar 2015 Link to this post

    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.

     
  5. Delvis
    Delvis avatar
    18 posts
    Member since:
    Mar 2012

    Posted 05 Mar 2015 in reply to Kostadin Link to this post

    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?
  6. Delvis
    Delvis avatar
    18 posts
    Member since:
    Mar 2012

    Posted 06 Mar 2015 in reply to Kostadin Link to this post

    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();
            }
        }
    }
  7. Answer
    Kostadin
    Admin
    Kostadin avatar
    1711 posts

    Posted 10 Mar 2015 Link to this post

    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.

     
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017