I am having difficulty with a basic user control. All I want to do is change an image in the control based on a value in a grid. The user control is a template in the grid. What seems to be happening is the value assigned to a property of the user control
in the aspx page reverts back to null when control goes back to the user control. Hope that makes sense.
Seems that the value has a context problem that I cannot work out how to correct.
Code is listed below....
PercentageCompleteImage.ascx (Just an image referencing the first of 10 images in the root directory)
<%
@
Control
Language="C#"
AutoEventWireup="true"
CodeFile="PercentageCompleteImage.ascx.cs"
Inherits="PercentageCompleteImage"%>
<
asp:Image
ID="Image1"
runat="server"
ImageUrl="~/0_Perc_Comp.png"
OnLoad="SetPercentageCompleteImage"/>
PercentageCompleteImage.ascx.cs
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public
partial
class
PercentageCompleteImage : System.Web.UI.UserControl
{
protected
void Page_Load(object sender,
EventArgs e) { }
public
string _PerCentValue; // Field that is set on the default.aspx by the template
public
string PerCentValue
{
get {
return _PerCentValue; }
set { _PerCentValue =
value; } }
public
void SetPercentageCompleteImage(object sender,
EventArgs e) {
int x =
Convert.ToInt32(PerCentValue);
switch (x) {
case 0: Image1.ImageUrl =
"~/0_Perc_Comp.png";
return;
case 1: Image1.ImageUrl =
"~/10_Perc_Comp.png";
return;
case 2: Image1.ImageUrl =
"~/20_Perc_Comp.png";
return;
default: Image1.ImageUrl =
"~/30_Perc_Comp.png";
return;
} } }
Default.aspx (Important elements only...no code behind page)
<telerik:GridBoundColumn
CurrentFilterFunction="NoFilter"
DataField="Status"
FilterListOptions="VaryByDataType"
ForceExtractValue="None"
HeaderText="Status"
ReadOnly="True"
SortExpression="Status"
UniqueName="Status">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn
CurrentFilterFunction="NoFilter"
FilterListOptions="VaryByDataType"
ForceExtractValue="None"
UniqueName="column"
HeaderText="Status">
<EditItemTemplate>
<asp:TextBox
runat="server"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<uc1:PercentageCompleteImage
ID="PercentageCompleteImage1"
runat="server"
PerCentValue='<%# DataBinder.Eval(Container, "DataItem.Status") %>'
/>
//the PerCentValue gets its value from the Status section above. This is the value that becomes null on control returning to the user control
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
you make an error on a class attribute persistence.
PerCentValue='<%# DataBinder.Eval(Container, "DataItem.Status") %>'
It's only a initialization (and the value is setup in the first page access). When you perform a postback you lost this value. You need to store it somewhere like viewstate.
Try to remove _PerCentValue attribute and modify property with this one:
public string PerCentValue
{
get {
return (string)ViewState["PerCentValue"]; }
set { ViewState["PerCentValue"] =
value; } }
Wamba {WamBlog}Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
Thanks for the suggestion. Certainly understand what viewstate is all about now.
However the problem still persists. The value is assigned to PerCentValue whilst the control is with default.aspx. Once control moves to the user control (PercentageCompleteImage.ascx) particularly in the SetPercentageCompleteImage class the value of PerCentValue
change back to null.
Not sure if there is something more fundementally incorrect here.
I suppose is an incapsulation problem. I need more informations about the main control: Is Ascx or server control? when you look for PerCentValue? How do u manage internal control?
Wamba {WamBlog}Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
I have recreated the solution using your recommendation above but using standard controls (not Telerik's RADGrid) so it is shorter/simpler and easier to post here. I also created a basic table (Fields: StatusID and Status) to use as a source via LINQ.
Default.aspx[This is very basic. Just a GridView with a template column added for the user control]
System; using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public
partial
class
_Default : System.Web.UI.Page
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public
partial
class
WebUserControl : System.Web.UI.UserControl
{
public
String PerCentValue
{
get {
return (string)ViewState["PerCentValue"];
}
set { ViewState["PerCentValue"] =
value; } }protected
void Page_Load(object sender,
EventArgs e)
{ }
public
void SetPercentageCompleteImage(object sender,
EventArgs e)
{ int x=0 ;if(PerCentValue==null)
{ x = 0; }
else
{ x = int.Parse(PerCentValue); }
switch (x)
{ case 0: Image1.ImageUrl =
"~/Images/Image1.PNG";
return;
case 1: Image1.ImageUrl =
"~/Images/Image2.PNG";
return;
default: Image1.ImageUrl =
"~/Images/Image3.PNG";
return; }
1) "SetPercentageCompleteImage" it's call on each postback? Why do u use
OnLoad="SetPercentageCompleteImage"
of image instead of Onload event of your custom control?
2) Try to semplify replace your control with a textbox and bind PerCentValue as text property. If this doesn't work may be a bind problem.
Wamba {WamBlog}Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
Certainly runs okay. Just that the IF logic catches the nulls and sets the image to display the first one.
I tried changing to a SQL Connection (rather than LINQ) but still works the same. PerCentValue reverts to Null when control returns to the user control.
1) The SetPercentageCompleteImage seems to be called on each postback. Not sure why I used the OnLoad. Seemed like the way to do this. Open to advise here (be quite specific though).
2) Did not try this but have worked on another user control that does something similar and it works. See
http://forums.asp.net/t/1258174.aspx (Very Basic Custom Control).
if(Page.IsPostBack){return;} as the first instruction of SetPercentageCompleteImage.
Check if databind function is call on pastback.
Wamba {WamBlog}Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
Hey stop all! I suppose you find the bug, If IsPostBack is false no viewstate information is postback. How do u do the postback?
Wamba {WamBlog}Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
brad_bondi
0 Points
17 Posts
Value not passing to User Control Code Behind page
May 13, 2008 12:43 PM|LINK
I am having difficulty with a basic user control. All I want to do is change an image in the control based on a value in a grid. The user control is a template in the grid. What seems to be happening is the value assigned to a property of the user control in the aspx page reverts back to null when control goes back to the user control. Hope that makes sense.
Seems that the value has a context problem that I cannot work out how to correct.
Code is listed below....
PercentageCompleteImage.ascx (Just an image referencing the first of 10 images in the root directory)
<%
@ Control Language="C#" AutoEventWireup="true" CodeFile="PercentageCompleteImage.ascx.cs" Inherits="PercentageCompleteImage"%><
asp:Image ID="Image1" runat="server" ImageUrl="~/0_Perc_Comp.png" OnLoad="SetPercentageCompleteImage"/> PercentageCompleteImage.ascx.cs using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; public partial class PercentageCompleteImage : System.Web.UI.UserControl{
protected void Page_Load(object sender, EventArgs e) { } public string _PerCentValue; // Field that is set on the default.aspx by the template public string PerCentValue{
get { return _PerCentValue; } set { _PerCentValue = value; } } public void SetPercentageCompleteImage(object sender, EventArgs e) { int x = Convert.ToInt32(PerCentValue); switch (x) { case 0: Image1.ImageUrl = "~/0_Perc_Comp.png"; return; case 1: Image1.ImageUrl = "~/10_Perc_Comp.png"; return; case 2: Image1.ImageUrl = "~/20_Perc_Comp.png"; return; default: Image1.ImageUrl = "~/30_Perc_Comp.png"; return;} } }
Default.aspx (Important elements only...no code behind page)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><%
@ Register src="PercentageCompleteImage.ascx" tagname="PercentageCompleteImage" tagprefix="uc1" %><%
@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>...
<telerik:GridBoundColumn CurrentFilterFunction="NoFilter" DataField="Status" FilterListOptions="VaryByDataType" ForceExtractValue="None" HeaderText="Status" ReadOnly="True" SortExpression="Status" UniqueName="Status"> </telerik:GridBoundColumn> <telerik:GridTemplateColumn CurrentFilterFunction="NoFilter" FilterListOptions="VaryByDataType" ForceExtractValue="None" UniqueName="column" HeaderText="Status"> <EditItemTemplate> <asp:TextBox runat="server"></asp:TextBox> </EditItemTemplate> <ItemTemplate> <uc1:PercentageCompleteImage ID="PercentageCompleteImage1" runat="server" PerCentValue='<%# DataBinder.Eval(Container, "DataItem.Status") %>' /> //the PerCentValue gets its value from the Status section above. This is the value that becomes null on control returning to the user control </ItemTemplate> </telerik:GridTemplateColumn> </Columns>Wamba
Member
404 Points
72 Posts
Re: Value not passing to User Control Code Behind page
May 13, 2008 01:07 PM|LINK
Hi Brad!
you make an error on a class attribute persistence.
PerCentValue='<%# DataBinder.Eval(Container, "DataItem.Status") %>' It's only a initialization (and the value is setup in the first page access). When you perform a postback you lost this value. You need to store it somewhere like viewstate.
Try to remove _PerCentValue attribute and modify property with this one:
public string PerCentValue{
get { return (string)ViewState["PerCentValue"]; } set { ViewState["PerCentValue"] = value; } }Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
brad_bondi
0 Points
17 Posts
Re: Value not passing to User Control Code Behind page
May 14, 2008 03:13 AM|LINK
Wamba,
Thanks for the suggestion. Certainly understand what viewstate is all about now.
However the problem still persists. The value is assigned to PerCentValue whilst the control is with default.aspx. Once control moves to the user control (PercentageCompleteImage.ascx) particularly in the SetPercentageCompleteImage class the value of PerCentValue change back to null.
Not sure if there is something more fundementally incorrect here.
Any recommendations.
Brad
Wamba
Member
404 Points
72 Posts
Re: Value not passing to User Control Code Behind page
May 14, 2008 05:50 AM|LINK
Hi brad_bondi,
I suppose is an incapsulation problem. I need more informations about the main control: Is Ascx or server control? when you look for PerCentValue? How do u manage internal control?
Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
brad_bondi
0 Points
17 Posts
Re: Value not passing to User Control Code Behind page
May 14, 2008 08:03 AM|LINK
Wamba,
I have recreated the solution using your recommendation above but using standard controls (not Telerik's RADGrid) so it is shorter/simpler and easier to post here. I also created a basic table (Fields: StatusID and Status) to use as a source via LINQ.
Default.aspx [This is very basic. Just a GridView with a template column added for the user control]
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableViewState="true" %><%
@ Register src="WebUserControl.ascx" tagname="WebUserControl" tagprefix="uc1" %> <!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>Untitled Page</title></
head><
body> <form id="form1" runat="server"> <div> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="StatusID" DataSourceID="LinqDataSource1"> <Columns> <asp:BoundField DataField="StatusID" HeaderText="StatusID" ReadOnly="True" SortExpression="StatusID" /> <asp:BoundField DataField="Status1" HeaderText="Status1" SortExpression="Status1" /> <asp:TemplateField> <ItemTemplate> <uc1:WebUserControl ID="WebUserControl1" runat="server" PerCentValue='<%# DataBinder.Eval(Container, "DataItem.Status1") %>' /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="DataClassesDataContext" TableName="Status"> </asp:LinqDataSource> </div> </form> </body> </html>Default.aspx.cs [Nothing added here]
using
System; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; public partial class _Default : System.Web.UI.Page{
protected void Page_Load(object sender, EventArgs e) { } }WebUserControl.ascx [Note the OnLoad parameter]
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %><
asp:Image ID="Image1" runat="server" Height="21px" ImageUrl="~/Images/Image1.PNG" Width="125px" OnLoad="SetPercentageCompleteImage" />WebUserControl.ascx.cs
using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; public partial class WebUserControl : System.Web.UI.UserControl { public String PerCentValue{
get { return (string)ViewState["PerCentValue"]; } set { ViewState["PerCentValue"] = value; } }protected void Page_Load(object sender, EventArgs e){ }
public void SetPercentageCompleteImage(object sender, EventArgs e) { int x=0 ;if(PerCentValue==null){ x = 0; }
else { x = int.Parse(PerCentValue); } switch (x) { case 0: Image1.ImageUrl = "~/Images/Image1.PNG"; return; case 1: Image1.ImageUrl = "~/Images/Image2.PNG"; return; default: Image1.ImageUrl = "~/Images/Image3.PNG"; return; }} }
Wamba
Member
404 Points
72 Posts
Re: Value not passing to User Control Code Behind page
May 14, 2008 08:41 AM|LINK
It seems to be ok... [8-)]
Some question e try for you:
1) "SetPercentageCompleteImage" it's call on each postback? Why do u use OnLoad="SetPercentageCompleteImage" of image instead of Onload event of your custom control?
2) Try to semplify replace your control with a textbox and bind PerCentValue as text property. If this doesn't work may be a bind problem.
Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
brad_bondi
0 Points
17 Posts
Re: Value not passing to User Control Code Behind page
May 14, 2008 12:59 PM|LINK
Wamba,
Certainly runs okay. Just that the IF logic catches the nulls and sets the image to display the first one.
I tried changing to a SQL Connection (rather than LINQ) but still works the same. PerCentValue reverts to Null when control returns to the user control.
1) The SetPercentageCompleteImage seems to be called on each postback. Not sure why I used the OnLoad. Seemed like the way to do this. Open to advise here (be quite specific though).
2) Did not try this but have worked on another user control that does something similar and it works. See http://forums.asp.net/t/1258174.aspx (Very Basic Custom Control).
Thanks again
Brad
Wamba
Member
404 Points
72 Posts
Re: Value not passing to User Control Code Behind page
May 14, 2008 01:11 PM|LINK
try with this: ...
if(Page.IsPostBack){return;} as the first instruction of SetPercentageCompleteImage.
Check if databind function is call on pastback.
Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.
brad_bondi
0 Points
17 Posts
Re: Value not passing to User Control Code Behind page
May 15, 2008 04:59 AM|LINK
Wamba,
Hi again.
Tried adding the postback. When I run in debug mode the IsPostBack is showing as FALSE.
How do I check if databind is calledon postback?
Brad
Wamba
Member
404 Points
72 Posts
Re: Value not passing to User Control Code Behind page
May 15, 2008 08:07 AM|LINK
Hey stop all! I suppose you find the bug, If IsPostBack is false no viewstate information is postback. How do u do the postback?
Dont forget to click "Mark as Answer" on the post that helped you.
This credits the member,earns you a point & marks your thread as Resolved.