locked
Value not passing to User Control Code Behind page RRS feed

  • Question

  • User1858242605 posted

    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>

     

    Tuesday, May 13, 2008 8:43 AM

Answers

  • User-1566612352 posted

    try with this: ...

    if(Page.IsPostBack){return;}  as the first instruction of SetPercentageCompleteImage.

    Check if databind function is call on pastback.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, May 14, 2008 9:11 AM

All replies

  • User-1566612352 posted

    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; } }

    Tuesday, May 13, 2008 9:07 AM
  • User1858242605 posted

    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

    Tuesday, May 13, 2008 11:13 PM
  • User-1566612352 posted

    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?

    Wednesday, May 14, 2008 1:50 AM
  • User1858242605 posted

     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; }

    } }

    Wednesday, May 14, 2008 4:03 AM
  • User-1566612352 posted

    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.

    Wednesday, May 14, 2008 4:41 AM
  • User1858242605 posted

    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

     

    Wednesday, May 14, 2008 8:59 AM
  • User-1566612352 posted

    try with this: ...

    if(Page.IsPostBack){return;}  as the first instruction of SetPercentageCompleteImage.

    Check if databind function is call on pastback.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, May 14, 2008 9:11 AM
  • User1858242605 posted

    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

    Thursday, May 15, 2008 12:59 AM
  • User-1566612352 posted

    Hey stop all! I suppose you find the bug, If IsPostBack is false no viewstate information is postback. How do u do the postback?

    Thursday, May 15, 2008 4:07 AM
  • User1858242605 posted

     Wamba, below is the listing WebUserControl.ascx.cs with the ISPostBack logic added (in bold):

    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 {

    { get { return (string)ViewState["PerCentValue"]; }

    set { ViewState["PerCentValue"] = value; } }
    protected void Page_Load(object sender, EventArgs e)

    { }

    public void SetPercentageCompleteImage(object sender, EventArgs e)

                if (Page.IsPostBack)
                {
                    return;
                }

    { 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; }

    } }

     

    Thursday, May 15, 2008 5:13 AM
  • User-1566612352 posted

    Sorry, I wasn't clear.

    I wonna know what couse postback, like <asp:button > click, javascript or else with code.

    Thursday, May 15, 2008 5:24 AM
  • User1858242605 posted

    Wamba,

    Hi.  I am just loading the page (default.aspx).

    Brad 

    Thursday, May 15, 2008 7:43 AM
  • User1858242605 posted

    Wamba,

    Hi. Just solved it. Not a bug.

    Changed the method in the User Control from OnLoad to OnDataBinding. See below.

    <%@ 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" OnDataBinding="SetPercentageCompleteImage"  />

    Works fine now.

    Thanks for your assistance.

    Brad 

    Thursday, May 15, 2008 8:19 AM
  • User-1566612352 posted

    You are welcame :)

    Thursday, May 15, 2008 8:42 AM