ASPX templates
Version 7.x > ASPX templates > Datagrid Viewstate disappearing? View modes: 
User avatar
Member
Member
aaron.vanmeter-bluerhino - 2/3/2014 2:58:13 PM
   
Datagrid Viewstate disappearing?
In the process of upgrading a ASPX template-based v4.0 site to v7.0, and I've come across a problem where datagrids which work in the old system are no longer working in 7. Eventually, I created 2 test pages within the solution, one as a standard .aspx page and one as a Kentico template page, and turned on View State debugging for the Kentico one.

The standard .aspx page works as expected, allowing editing and deleting of the DataGrid rows. However, the Kentico template page does not.

The datagrid is loaded and the data is displayed correctly on the first page load:
User image

But when any of the Command buttons are clicked, the corresponding command handler is not triggered and the viewstate data disappears (although it says there are still 9 items in the grid):
User image

The page is set up exactly like the example at DataGrid.EditCommand Event, except that it inherits from the TemplatePage class instead of System.Web.UI.Page.


User avatar
Kentico Support
Kentico Support
kentico_jurajo - 2/4/2014 2:52:11 AM
   
RE:Datagrid Viewstate disappearing?
Hi,

What are you using in the master page template?

Is it cms:CMSPortalManager or cms:CMSPageManager? Could you please try using the other one? :-)

Also, what is the page template markup and code behind please?

Best regards,
Juraj Ondrus

User avatar
Member
Member
aaron.vanmeter-bluerhino - 2/4/2014 9:29:03 AM
   
RE:Datagrid Viewstate disappearing?
Juraj,

I was using CMSPortalManager, because the 7.0 Developer's Guide section on Creating ASPX master pages says to use it, and that it is the replacement for CMSPageManager.

You may use the CMSPageManager control instead of the CMSPortalManager. This control is an older equivalent available for the purposes of backwards compatibility. It does not support ASPX templates containing portal engine web part or widget zones.

Switching to the CMSPageManager does seem to fix the problem, but if they are equivalents, why should one work and not the other? If in the future we decide to do dual-template and portal development, will the same problem occur on pages that have data grids?

Page template markup:

<%@ Page Title="" Language="C#" MasterPageFile="~/CMSTemplates/BlueRhinoDPASPX/Test.master" AutoEventWireup="true" CodeFile="DataGrid_Test2.aspx.cs" Inherits="BRCPages_Test_DataGrid_Test2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="plcMain" Runat="Server">
<h3>DataGrid Editing Example</h3>

<asp:DataGrid id="ItemsGrid"
BorderColor="black"
BorderWidth="1"
CellPadding="3"
OnEditCommand="ItemsGrid_Edit"
OnCancelCommand="ItemsGrid_Cancel"
OnUpdateCommand="ItemsGrid_Update"
OnItemCommand="ItemsGrid_Command"
AutoGenerateColumns="false"
runat="server" EnableViewState="true" ViewStateMode="Enabled">

<HeaderStyle BackColor="#aaaadd">
</HeaderStyle>

<Columns>

<asp:EditCommandColumn
EditText="Edit"
CancelText="Cancel"
UpdateText="Update"
HeaderText="Edit item">

<ItemStyle Wrap="False">
</ItemStyle>

<HeaderStyle Wrap="False">
</HeaderStyle>

</asp:EditCommandColumn>

<asp:ButtonColumn
HeaderText="Delete item"
ButtonType="LinkButton"
Text="Delete"
CommandName="Delete"/>

<asp:BoundColumn HeaderText="Item"
ReadOnly="True"
DataField="Item"/>

<asp:BoundColumn HeaderText="Quantity"
DataField="Qty"/>

<asp:BoundColumn HeaderText="Price"
DataField="Price"
DataFormatString="{0:c}"/>

</Columns>

</asp:DataGrid>
</asp:Content>


Page template code-behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using CMS.UIControls;

public partial class BRCPages_Test_DataGrid_Test2 : TemplatePage
{
// The Cart and CartView objects temporarily store the data source
// for the DataGrid control while the page is being processed.
DataTable Cart = new DataTable();
DataView CartView;

protected void Page_Load(Object sender, EventArgs e)
{
// With a database, use an select query to retrieve the data. Because
// the data source in this example is an in-memory DataTable, retrieve
// the data from session state if it exists; otherwise, create the data
// source.
GetSource();

// The DataGrid control maintains state between posts to the server;
// it only needs to be bound to a data source the first time the page
// is loaded or when the data source is updated.
if (!IsPostBack)
{

BindGrid();

}

}

protected void ItemsGrid_Edit(Object sender, DataGridCommandEventArgs e)
{

// Set the EditItemIndex property to the index of the item clicked
// in the DataGrid control to enable editing for that item. Be sure
// to rebind the DateGrid to the data source to refresh the control.
ItemsGrid.EditItemIndex = e.Item.ItemIndex;
BindGrid();

}

protected void ItemsGrid_Cancel(Object sender, DataGridCommandEventArgs e)
{

// Set the EditItemIndex property to -1 to exit editing mode.
// Be sure to rebind the DateGrid to the data source to refresh
// the control.
ItemsGrid.EditItemIndex = -1;
BindGrid();

}

protected void ItemsGrid_Update(Object sender, DataGridCommandEventArgs e)
{

// Retrieve the text boxes that contain the values to update.
// For bound columns, the edited value is stored in a TextBox.
// The TextBox is the 0th control in a cell's Controls collection.
// Each cell in the Cells collection of a DataGrid item represents
// a column in the DataGrid control.
TextBox qtyText = (TextBox)e.Item.Cells[3].Controls[0];
TextBox priceText = (TextBox)e.Item.Cells[4].Controls[0];

// Retrieve the updated values.
String item = e.Item.Cells[2].Text;
String qty = qtyText.Text;
String price = priceText.Text;

DataRow dr;

// With a database, use an update command to update the data.
// Because the data source in this example is an in-memory
// DataTable, delete the old row and replace it with a new one.

// Remove the old entry and clear the row filter.
CartView.RowFilter = "Item='" + item + "'";
if (CartView.Count > 0)
{
CartView.Delete(0);
}
CartView.RowFilter = "";

// ***************************************************************
// Insert data validation code here. Be sure to validate the
// values entered by the user before converting to the appropriate
// data types and updating the data source.
// ***************************************************************

// Add the new entry.
dr = Cart.NewRow();
dr[0] = Convert.ToInt32(qty);
dr[1] = item;

// If necessary, remove the '$' character from the price before
// converting it to a Double.
if (price[0] == '$')
{
dr[2] = Convert.ToDouble(price.Substring(1));
}
else
{
dr[2] = Convert.ToDouble(price);
}

Cart.Rows.Add(dr);

// Set the EditItemIndex property to -1 to exit editing mode.
// Be sure to rebind the DateGrid to the data source to refresh
// the control.
ItemsGrid.EditItemIndex = -1;
BindGrid();

}

protected void BindGrid()
{

// Set the data source and bind to the Data Grid control.
ItemsGrid.DataSource = CartView;
ItemsGrid.DataBind();

}

protected void GetSource()
{

// For this example, the data source is a DataTable that is stored
// in session state. If the data source does not exist, create it;
// otherwise, load the data.
if (Session["ShoppingCart"] == null)
{

// Create the sample data.
DataRow dr;

// Define the columns of the table.
Cart.Columns.Add(new DataColumn("Qty", typeof(Int32)));
Cart.Columns.Add(new DataColumn("Item", typeof(String)));
Cart.Columns.Add(new DataColumn("Price", typeof(Double)));

// Store the table in session state to persist its values
// between posts to the server.
Session["ShoppingCart"] = Cart;

// Populate the DataTable with sample data.
for (int i = 1; i <= 9; i++)
{
dr = Cart.NewRow();
if (i % 2 != 0)
{
dr[0] = 2;
}
else
{
dr[0] = 1;
}
dr[1] = "Item " + i.ToString();
dr[2] = (1.23 * (i + 1));
Cart.Rows.Add(dr);
}

}

else
{

// Retrieve the sample data from session state.
Cart = (DataTable)Session["ShoppingCart"];

}

// Create a DataView and specify the field to sort by.
CartView = new DataView(Cart);
CartView.Sort = "Item";

return;

}

protected void ItemsGrid_Command(Object sender, DataGridCommandEventArgs e)
{

switch (((LinkButton)e.CommandSource).CommandName)
{

case "Delete":
DeleteItem(e);
break;

// Add other cases here, if there are multiple ButtonColumns in
// the DataGrid control.

default:
// Do nothing.
break;

}

}

protected void DeleteItem(DataGridCommandEventArgs e)
{

// e.Item is the table row where the command is raised. For bound
// columns, the value is stored in the Text property of a TableCell.
TableCell itemCell = e.Item.Cells[2];
string item = itemCell.Text;

// Remove the selected item from the data source.
CartView.RowFilter = "Item='" + item + "'";
if (CartView.Count > 0)
{
CartView.Delete(0);
}
CartView.RowFilter = "";

// Rebind the data source to refresh the DataGrid control.
BindGrid();

}
}


Test.master markup:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Test.master.cs" Inherits="CMSTemplates_BlueRhinoDPASPX_Test" %>

<%=DocType%>

<html xmlns="http://www.w3.org/1999/xhtml" <%=XmlNamespace%>>
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<asp:literal runat="server" id="ltlTags" enableviewstate="false" />
</head>
<body class="<%=BodyClass%>" <%=BodyParameters%>>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder runat="server" ID="plcManagers">
<cms:CMSPageManager ID="CMSPageManager1" runat="server" EnableViewState="false" />
<ajaxToolkit:ToolkitScriptManager ID="manScript" runat="server" EnableViewState="false" ScriptMode="Release" />
</asp:PlaceHolder>
<cms:CMSMenu ID="cmsmenu1" runat="server" Cursor="Pointer" HighlightAllItemsInPath="true" Layout="Horizontal" Padding="0" Spacing="1" />
<asp:ContentPlaceHolder ID="plcMain" runat="server"></asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>


Test.master code-behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CMS.UIControls;

public partial class CMSTemplates_BlueRhinoDPASPX_Test : TemplateMasterPage
{
protected override void CreateChildControls()
{
base.CreateChildControls();
PageManager = CMSPageManager1;
}

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.ltlTags.Text = this.HeaderTags;
}

protected void Page_Load(object sender, EventArgs e)
{

}
}

User avatar
Kentico Support
Kentico Support
kentico_jurajo - 2/5/2014 3:19:49 AM
   
RE:Datagrid Viewstate disappearing?
Hello,

Thank you. What is the hotfix number that was applied after the upgrade?

Also, could you please modify the master template to look like this (notice also the order of the controls):

...
<ajaxToolkit:ToolkitScriptManager ID="manScript" runat="server" EnableViewState="false"
ScriptMode="Release" />
<cms:CMSPortalManager ID="manPortal" runat="server" EnableViewState="false" />
</asp:PlaceHolder>
<cms:ContextMenuPlaceHolder ID="plcCtx" runat="server" />
...


Best regards,
Juraj Ondrus