Link to home
Start Free TrialLog in
Avatar of x666xchange
x666xchange

asked on

ASP.NET. Using private variables and property methods instead of state bags.


I compiled and used the below custom control in the .aspx page also pasted below. It worked smoothly when state management was done using StateBags and I was able to increment the font-size of the text displayed.

Custom Control Code
===================

Imports System
Imports System.Web
Imports System.Web.UI

Namespace MyCustomControls
     Public Class CustomControl2 : Inherits Control
          Private strMessage As String = "This is my custom control !"
          Private nSize As Integer

          Public Property Message As String
               Get
                    Message = ViewState(“Message”).ToString
               End get

               Set
                    strMessage = Value
               End Set
          End Property

          Public Property Size As Integer
               Get
                    Size = CType(ViewState("Size"),Integer)
               End get

               Set
                    ViewState("Size") = Value
               End Set
          End Property


          Protected Overrides Sub Render(Output As HtmlTextWriter)
               Output.Write("<FONT Size=" & Me.Size & ">" & Me.Message & "</FONT>")
          End Sub

     End Class
End Namespace

.ASPX Page Code
===============

<%@ Page Language="VB" %>
<%@ Register TagPrefix="ACME" Namespace="MyCustomControls" Assembly="cc" %>

<SCRIPT Runat="server">
     Sub Submit(Obj As Object, E As EventArgs)
          MyControl.Size = MyControl.Size + 1
     End Sub
</SCRIPT>

<html>
<body>
     <form runat="server">
          The custom control produces the following output: <p>
          <ACME:CustomControl2 Id="MyControl" Message="Hello World !!!" Size="1" Runat="server" />
          <asp:Button Text="Increase Size" OnClick="Submit" Runat="server" />
     </form>
</body>
</html>


However I changed the code of the above custom control to use private properties and property methods combined as follows. But this time round, the increment of the font-size of the text works only for the first click on the button. Afterwards it doesn’t work i.e., the font-size increases only on the first click and subsequent clicks on the button produce no result. What is going wrong and how can I achieve the desired functionality using private variables and public property methods combined. What change is necessary in the below code ?

Imports System
Imports System.Web
Imports System.Web.UI

Namespace MyCustomControls
     Public Class CustomControl2 : Inherits Control
          Private strMessage As String
          Private nSize As Integer

          Public Property Message As String
               Get
                    Message = strMessage
               End get

               Set
                    strMessage = Value
               End Set
          End Property

          Public Property Size As Integer
               Get
                    Size = nSize
               End get

               Set
                    nSize = Value
               End Set
          End Property


          Protected Overrides Sub Render(Output As HtmlTextWriter)
               Output.Write("<FONT Size=" & Me.Size & ">" & Me.Message & "</FONT>")
          End Sub

     End Class
End Namespace


Avatar of CJ_S
CJ_S
Flag of Netherlands image

You really NEED the StateBag since that is the place where the values are actually stored. The chance you need to make is create another kind of StateBag to retrieve the last setting.
Avatar of x666xchange
x666xchange

ASKER

But then how would u explain the functionality working the first time round with private nSize integer variable and public Size property. The font does get increased when the page is loaded for te hfirst time and I click the button on the page. I checked the rendered source code after clicking the button for the first time. It shows the initial Size property value of "1" for the control incremented to "2". So what exactly is happening the first time, what is not happening on subsequent clicks and why ?

And how exactly is state ((( not ))) persisted when I use private vatiables.
ASKER CERTIFIED SOLUTION
Avatar of CJ_S
CJ_S
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Dear CJ,

I had posted the same query in the section "Active Server Pages (ASP)". Kinldy do check those out too. Its a request. :-)

Considering your answer and the comments posted there, your answer comes closest to the hunch that I had but in a very vague manner. I wasn't able clearly able to lay my finger squarely on the stagewise flow of things that must be occuring. So am glad that in a way, I was on the right track.

However there does exist certain areas of ambiguity still which is....

1) When the page is rendered in the browser for the very first time, is the value of "1" for the Size property included in the Base64 encoded value of the Hidden ViewState form field ?

If "YES", wouldn't this value be submitted to the server during postback when the button is clicked for the very first time.

2) Quoting your words :-

"sets the default value of the
object to 1 and then checks if any action has been taken. Yes, it has and goes to the function. Within
the function 1 is added to the default value 1, which will then be 2.
The page shows before the user and shows the correct size, 2."

So when the page finally shows before the user with the property value of Size set to "2" are you saying that this value is not included in the Base64 encoded ViewState hidden form field value this time ?

In the other section that I mentioned and where I had posted the same query, in the 2nd posting of the only respondent on that page, he mentions that when the page is rendered and the Size property on the control is called, the value from ViewState is retrieved. So what is got is the value from ViewState.

This aspect seems very, very contradictory to me if you were to maintain that ViewState were not being saved or maintained at all no matter how many times the page were being rendered.

My hunch is that ViewState sure is saved the first time round with "1" as the Size property value, posted back, incremented and re-assigned to the Control but not saved in the Base64 encoded value the 2nd time round. I guess what I mean to say is that the Base64 encoded ViewState value is not looked up when the value "2" is assigned to the Size property of the control

Kindly provide your opinion considering these arguments of mine and do correct me where I'm going off-track.
Avatar of Göran Andersson
The ViewState field only contains what is put there. Unless you set a value to ViewState("Size") there is no value for it in the statebag. The Size property of the control is not the same thing as ViewState("Size").

The property in the control tag does not put anything in the statebag by itself. By writing Size="1" in the tag, you only set the value of Size to "1" when the control is created.

Remember that the control is recreated each time the page is created. When the code has run and the page is sent to the client, the control object is destroyed and all it's properties are lost.
Dear GreenGhost,

But my point is still being missed out...

If the ViewState is not storing or getting affected in anyw way, how then is the control rendered in the client with the incremented Size property value of "2"

This would clearly mean that the ViewState has no direct relation of being looked up by the control during rendering to fill up the value of its properties ("Size" for eg) as another gentleman had stated. Its Size property value just gets incremented to "2". Is that what u are trying to say ? Kindly explain.

SECONDLY, and quoting you ...

"
By writing Size="1"
in the tag, you only set the value of Size to "1" when the control is created.
"

So are u saying that even the first time round that the page is rendered, not even the default value of 1 is stored in the Base64 encoded value of the Hidden form field variable.

When the page get posted back, the control is recreated with the default value Size="1". Then the Submit sub is run, adding one to this value. That is why you get the value "2" when the page has been posted back.

If you post it back again, the control will still be recreated using the default value="1", and the Submit sub will again add one to it, so you will always get the value "2", no matter how many times you post it.

Unless you use ViewState in the code of your control, nothing is stored in it's statebag. The local variables of your control does only exist inside the control, they are not included in the statebag.

The hidden field contains the ViewState of all controls on the page, nothing more. (Nothing more that is relevant here, at least... I don't really know enough yet to say that it isn't used for something else...)

(After all, if all properties of all controls would be stored in the statebag, the hidden field would be as big as the rest of the page...)

The Size property (for an example) does not even have a value, it only appears to have a value. When you set the property, the Set method is called to store the value somewhere. And when you read the property, the Get method is called to retrieve the value. Even when the control is created with the default value Size="1", the Set method is called to store this somewhere.
Hey CJ & GreenGhost,

How do I split the points posted for this query of mine between the 2 of u ?
Go to https://www.experts-exchange.com/commspt/. Post a question there with a link to this question and ask them to split points.

CJ
Dear GreenGhost,

Quoting you :

"
if all properties of all controls would be stored in the statebag, the hidden field would
be as big as the rest of the page...)
"

But then isn't that what ViewState is about and meant for ?
Saving the current view of a page and its controls including the property values of controls ?

Well, yes and no. The ViewState is meant for maintaining the current view, but that does not mean that all properties of all controls have to be saved.

Most properties of most controls will never change from the default value, so there is no need to save them. For an example, the Label class has 86 properties, but you seldom use more than one. The rest of them retain their default value, so they (fortunately) do not need to be saved.

Remember also that the properties actually doesn't have values. When you set the value of a property, it's stored somewhere else, like in a local variable, or if it has to be retained to the next page, in the statebag.

If the ViewState would automatically save all properties, it would have to get them from the properties' Get methods, then on the next page put them back with the properties' Set methods. But that would not work, as a property does not neccesary have to return what you set it to. Also, a property can be ReadOnly or WriteOnly, so there would be nothing to get or nowhere to put it back.

The ViewState is not automatic. You have to specify in the code of the control what data is supposed to be maintained to the next page.

Dear GreenGhost,

Considering your latest posting above, I had like to know something.

When a page is " first " compiled and rendered, is state saved in the hidden ViewState variable for the controls on the page.


If yes then what is it about those controls say for eg. a button or a label control that is actually saved ?
Or is no state saved at all for the controls on the page when the page is rendered for the " very " first time ?
The controls is of course designed to use the ViewState as little as possible, to minimise the size of the hidden field holding the state, so most control will probably not need to save anything. If needed they will put things in the ViewState, also when the page is created for the first time.

I haven't worked with the controls enough to tell you exactly what they put in their statebags. But as it's used to be able to recreate the control, I suppose any change you make from the default values, the control will have to save in its statebag.
x666xchange

You requested the points to be split between CJ_S and GreenGhost.

I reduced the points for this question from 100 to 50 points and refunded the remaining ones. Please accept one experts comment as an answer and post a separate 50p question for the other expert in this TA with a title like "Points for xxx" and a body "For your help with https://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=dot_net&qid=20309117".

** Mindphaser - Community Support Moderator **