Welcome Guest Search | Active Topics | Sign In | Register

Dynamically created CustomColumns vs. ClientSideBeginEdit not firing after postback Options
infoland
Posted: Wednesday, November 16, 2011 10:59:10 AM
Rank: Member
Groups: Member

Joined: 11/15/2011
Posts: 24
Hi,
as said in subject, I have a grid with some dynamically created CustomColumns.
The grid has FullRowMode=False.
After postback, ClientSideBeginEdit event for any CustomColumn is not fired.

I isolated the problem into a small project (derived from one of your standard demos).

Here's my ASPNET WebForm markup:
Code: HTML/ASPX
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>TEST EO WEB GRID</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <script type="text/javascript" language="javascript">
            function customColumn_getText(column, item, cellValue) {
                return '<span title="Cell code: ' + cellValue + '">' + cellValue + '</span>';
            }
            function customColumn_beginEdit(cell) {
                alert('beginEdit');
            }

            function customColumn_endEdit(cell, newValue) {
            }
        </script>

        <eo:Grid ID="Grid" runat="server" BorderColor="#C7D1DF" BorderWidth="1px" 
            ColumnHeaderAscImage="00050303" ColumnHeaderDescImage="00050304" 
            ColumnHeaderDividerImage="00050302" Font-Bold="False"
            Font-Italic="False" Font-Names="Tahoma" Font-Overline="False" Font-Size="8pt" 
            Font-Strikeout="False" Font-Underline="False" GridLineColor="199, 209, 223" 
            GridLines="Both" Height="200px" ItemHeight="19" Width="500px" 
            FullRowMode="False">
            <ItemStyles>
                <eo:GridItemStyleSet>
                    <ItemStyle CssText="background-color: white" />
                    <ItemHoverStyle CssText="background-image: url(00050206); background-repeat: repeat-x" />
                    <SelectedStyle CssText="background-image: url(00050207); background-repeat: repeat-x" />
                    <CellStyle CssText="padding-left:8px;padding-top:2px; color:#336699;white-space:nowrap;" />
                </eo:GridItemStyleSet>
            </ItemStyles>
            <Columns>
                <eo:RowNumberColumn></eo:RowNumberColumn>
            </Columns>
            <ColumnHeaderStyle CssText="background-image:url('00050301');padding-left:8px;padding-top:2px;font-weight: bold;color:white;" />
            <FooterStyle CssText="padding-bottom:4px;padding-left:4px;padding-right:4px;padding-top:4px;" />
        </eo:Grid>
    </div>
    <p>
	    <asp:Panel id="panChanges" Width="400px" runat="server" Visible="False">Change Summary:<br/></asp:Panel>
	    <asp:Button id="Button1" Text="Post Back!" Runat="server" OnClick="Button1_Click"></asp:Button>
    </p>
    </form>
</body>
</html>


And that's code-behind:
Code: Visual Basic.NET
Imports EO.Web
Imports System.Data

Public Class Test
    Inherits System.Web.UI.Page

    Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
        panChanges.Visible = True

        Dim s As String = String.Empty
        If Grid.ChangedItems.Length = 0 Then
            s += "No item has changed."
        Else
            Dim item As EO.Web.GridItem
            For Each item In Grid.ChangedItems
                Dim cell As EO.Web.GridCell
                For Each cell In item.Cells
                    If cell.Modified Then
                        Dim [text] As String = String.Format("Cell Changed: Key = {0}, Field = {1}, New Value = {2}", item.Key, cell.Column.DataField, cell.Value)

                        s += "<br />"
                        s += [text]
                    End If
                Next cell
            Next item
        End If

        Dim info As New Literal()
        info.Text = s
        panChanges.Controls.Add(info)
    End Sub

    Private Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
        BuildGridLayout()
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            With Grid
                .DataSource = BuildGridDataSource()
                .DataBind()
            End With
            Grid.Height = Grid.ItemHeight * Grid.Items.Count + Grid.ColumnHeaderHeight
        End If
    End Sub

    Private Sub BuildGridLayout()
        With Grid
            .Columns.Clear()
            .Columns.Add(New TextBoxColumn() With {.DataField = "Text", .HeaderText = "Text"})
            For i = 1 To 4
                Dim customColumn As New CustomColumn With { _
                        .DataField = "Code" & i, _
                        .HeaderText = "Code" & i, _
                        .Name = "Code" & i, _
                        .ClientSideGetText = "customColumn_getText", _
                        .ClientSideBeginEdit = "customColumn_beginEdit", _
                        .ClientSideEndEdit = "customColumn_endEdit", _
                        .EditorTemplate = New DummyTemplate
                    }

                .Columns.Add(customColumn)
            Next
        End With
    End Sub

    Private Function BuildGridDataSource() As DataTable
        Dim dt As New DataTable
        dt.Columns.Add("Text", GetType(String))
        For i = 1 To 4
            dt.Columns.Add("Code" & i, GetType(Integer))
        Next
        For r = 0 To 9
            Dim dr = dt.NewRow()
            dr("Text") = "Text " & r
            For i = 1 To 4
                dr("Code" & i) = (r + i) Mod 5
            Next
            dt.Rows.Add(dr)
        Next
        Return dt
    End Function
End Class

Public Class DummyTemplate
    Implements ITemplate

    Public Sub InstantiateIn(container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn
        container.Controls.Add(New LiteralControl(""))
    End Sub
End Class


After clicking "Post Back!" button, when one clicks over columns "Code1" etc. does not show the alert.

Any help is much appreciated.
Thanks
eo_support
Posted: Wednesday, November 16, 2011 12:13:15 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Please only dynamically create your columns when IsPostBack is false. What happens is the Grid tries to "replay" your changes to the Columns collection during post back after you have already manually added the columns again. That messed up the internal template controls which causes the Grid not rendering EditorTemplate for the dynamic columns, which in turned disabled editing mode and edit related events for the column.

Thanks!
infoland
Posted: Wednesday, November 16, 2011 12:40:32 PM
Rank: Member
Groups: Member

Joined: 11/15/2011
Posts: 24
Thanks for your fast reply, it's quite clear to me.
So I tried your suggestion, changing Page_Init event implementation as follows:

Code: Visual Basic.NET
Private Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
        If Not IsPostBack Then
            BuildGridLayout()
        End If
    End Sub


Unfortunately the problem still remains: after postback, edit events are not fired anymore.

The only way I managed to overcome this issue was disabling ViewState for the grid (and also removing the "If Not IsPostBack..." conditions, of course), but this isn't a suitable way for me since I do have to save grid changes.

Thanks again

eo_support
Posted: Wednesday, November 16, 2011 1:11:16 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Try to call BuildGridLayout inside Page_Load. That will recreate all the EditorTemplate. EditorTemplate can not be saved in view state, thus is lost while view state is loaded.

Thanks!
infoland
Posted: Wednesday, November 16, 2011 1:23:49 PM
Rank: Member
Groups: Member

Joined: 11/15/2011
Posts: 24
I'm sorry to tell you that it didn't work.
I changed code-behind as follows:

Code: Visual Basic.NET
' Suppressed Page_Init event...

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            BuildGridLayout()
            With Grid
                .DataSource = BuildGridDataSource()
                .DataBind()
            End With
            Grid.Height = Grid.ItemHeight * Grid.Items.Count + Grid.ColumnHeaderHeight
        End If
    End Sub


Still no edit events after postback...

EDIT:
I erroneously put BuildGridLayout under the "Not IsPostBack" condition!
Calling BuildGridLayout every time Page.Load is fired, it finally worked!

Code: Visual Basic.NET
' Suppressed Page_Init event...

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        BuildGridLayout()
        If Not IsPostBack Then
            With Grid
                .DataSource = BuildGridDataSource()
                .DataBind()
            End With
            Grid.Height = Grid.ItemHeight * Grid.Items.Count + Grid.ColumnHeaderHeight
        End If
    End Sub


Thank you very much for your support!
Bye

eo_support
Posted: Wednesday, November 16, 2011 1:37:46 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Yeah. That's it!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.