views:

91

answers:

3

OK, so I'm tyring to work with some simple stuff in ASP.NET and C# to get the hang of the super super basics, and I'm having trouble finding out how I can get this scope issue to work. At least, I think it's a scope issue! :)

So, here is my Default.aspx presentation markup:

<%@ Page Language="C#" Inherits="project1.Tree" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title>project1_test</title>
</head>
<body>
    <form runat="server">
        <p><asp:label runat="server" id="lblOutput" /></p>
        <asp:TextBox ID="txtGrowBy" runat="server" />
        <asp:Button id="btnGrow" runat="server" Text="Grow!!!" />
    </form>
</body>
</html>

And here is my CodeBehind file:

using System;
using System.Web;
using System.Web.UI;

namespace project1
{
    public partial class Tree : System.Web.UI.Page
    {

        public int height = 0;

        public void Grow(int heightToGrow) {
            height += heightToGrow;
        }

        protected void Page_Load(Object Source, EventArgs E)    
        {    
            Tree tree1 = new Tree();

            string msg = "Let's plant a tree!<br/>";        

            msg += "I've created a tree with a height of " +    
            tree1.height + " metres.<br/>";    

            lblOutput.Text = msg;
        }

        public virtual void btnGrowClicked (object sender, EventArgs args)
        {
            txtGrowBy.Text = tree1.heightToGrow;
        }

    }
}

Now, I believe the issue lies with the fact that I'm not using a getter and sender, but I'm not 100% sure.

+3  A: 

I take it you're variable height is not being maintained between postbacks?

This is because the web is stateless. Your variables are not maintained between postbacks unless you store the values in Session, ViewState or Hidden Fields. So you could do the following to maintain your height value between PostBacks:

ASPX:

<form runat="server">
    <asp:HiddenField id="hd_Height" runat="server" />
</form>

Code Behind:

public int Height
{
    get
    {
       return int.Parse(hd_Height.Value).ToString();
    }
    set
    {
        hd_Height.Value = value.ToString();
    }
}
GenericTypeTea
Thanks for the help, where should this block go in the CodeBehind file? Because this is to maintain the `height` value between PostBacks, placement of course matters, correct?
BOSS
In the page.cs file itself. It doesn't matter where you put it. You cannot put property declarations within methods. It must be put within the Tree class.
GenericTypeTea
+1  A: 

There's several immediate problems with your code; in the Page_Load method, you're creating a new Tree instance - you don't have to do this, as one was automatically created by IIS when the ASP.NET page was accessed. Use the this keyword in the Page_Load method to get access to that instance.

Further, nothing ever seems to call the Grow method; is this intentional? Shouldn't you be calling that from within the btnGrowClicked method?

And finally as GenericTypeTea points out, your height field won't be maintained between Postbacks. Easiest way to do this is with session state, eg:

private void PersistHeight(int height)
{
    this.Session["height"] = height;
}

private int RestoreHeight()
{
    return (int)this.Session["height"];
}
FacticiusVir
Is it different if I'm using Mono on a Mac, or is an instance automatically instantiated here as well. I haven't called the Grow method just because I wanted to solve this problem first, but I'll change that. Same question I asked GenericTypeTea, where should I be placing this Code Block?
BOSS
It's the same; Page_Load is an instance method, so an instance must exist for it to be called (you can tell this because there is no `static` keyword in the header). The code for both answers should go inside the class block, e.g.
FacticiusVir
public partial class Tree : System.Web.UI.Page { //Code goes in here }
FacticiusVir
Thanks for the extra info, any particular reason that Mono gives me `cannot implicitly convert type 'string' to 'int'`. I can post a new question if you want.
BOSS
It shouldn't do; it's possible that Mono hasn't fully implemented the type of the Session property, so try `Session[0]` instead of `Session["height"]`
FacticiusVir
A: 

You could use viewstate as well (if Mono supports it); simply add the updated value to viewstate before giving control back to the browser. Then read from viewstate the original value saved in the last postback and incrementing the new value to it:

public int MyValue { get {return Convert.ToInt32(viewstate["myVal"]);} set {viewstate["myVal"] = value;} }

I hope that makes sense.

Monkieboy