views:

194

answers:

4

Hi!

I have a custom control on my web form:

<form id="form" runat="server">
      <clc:CustomList 
        ID="myList" 
        runat="server" 
        AddButtonText="add"
        DeleteButtonText="del"
        MoveUpButtonText="up"
        MoveDownButtonText="down"/>
        <div id="test" runat="server"></div>
</form>

I need to get to this control from a static WebMethod. I get the Page object from current HttpContext, but it seems this page object has no contorls (controls count is 0).

[WebMethod]
public static List<CustomListControl.IListItem> GetListItems()
{
    Page page = HttpContext.Current.Handler as Page;

    Control control = null;

    if (page != null)
    {
        control = FindControlRecursive(page, "myList");
    }
    return null;
}

private static Control FindControlRecursive(Control root, string id)
{
    if (root.ID == id)
    {
        return root;
    }

    foreach (Control c in root.Controls)
    {
        Control t = FindControlRecursive(c, id);
        if (t != null)
        {
            return t;
        }
    }

    return null;
}

Any idea why or how to get to my control? Thanks!

A: 

Try with a standard control inside the page.
If you can find it by ID, then you probably did something wrong registering your custom control (maybe you could provide all the aspx code?).
Also note that the Page class has a builtin FindControl method.

For example, this should work:

<form id="form1" runat="server">
<div>
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</div>
</form>

and in the .cs file:

protected void Page_Load(object sender, EventArgs e) {
    var tb = FindControl("TextBox1");
}
Paolo Tedesco
I can get to control from the Page_Load event. I can't reach it from static WebMethod (seems like Page object I get from current HttpContext is not the real Page object :>)...
Heko
A: 

I post like this so I can append code...

ASPX:

<%@ Register Assembly="CustomListControl" Namespace="CustomListControl" TagPrefix="clc" %>
<%@ Import Namespace="System.Web.Services" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head id="head" runat="server">
    <title>MyList</title>
</head>
<body>
    <form id="form" runat="server">
        <clc:CustomList 
            ID="myList" 
            runat="server" 
            AddButtonText="add"
            DeleteButtonText="del"
            MoveUpButtonText="up"
            MoveDownButtonText="down"/>
            <div id="test" runat="server"></div>
    </form>
</body>
</html>

Even if I do

[WebMethod]
public static List<CustomListControl.IListItem> GetListItems()
{
    Page page = HttpContext.Current.Handler as Page;

    if (page != null)
    {
        var c = page.FindControl("myList");
    }
    return null;
}

I get c = null; I cant find even form control from this page object...

If I do var c = this.FindControl("myList") is page load event, I get to the control. Problem is because I cant get to contorl form static WebMethod...

Any idea why?

Heko
+1  A: 

You cannot access most properties and methods of the page instance and all controls on the page from within the Page Method. Why? Because page method call is not a postback, which means it doesn't go through the page life cycle, viewstate is not available, and controls are not created. Try to use an UpdatePanel instead.

Paulus E Kurniawan
I have a custom control (list of items with inline editing,jQuery drag and drop, adding and deleting functionality). When client makes a change, new state has to be (ajax) posted to the server (control). How to capture these events from UpdatePanel? Is it better to make an UpdatePanel inside of a custom control?I need something like this: custom control with actions which make ajax post from client to server when some events happen on the control. Any ideas how to do that?
Heko
By default all postback controls inside an update panel will trigger a partial postback. You can also make controls outside of the UpdatePanel as triggers or use __doPostBack to manually trigger a partial postback using javascript. Your control should publish an event where you can subscribe to from the page, you can then put your code logic in the event handler.
Paulus E Kurniawan
A: 

Static members can not reference instance references. You will need to pass in a reference to the HttpContext or the page itself from some other instance method in the class. I'd say you'd need to call the static web service with a parameter like this:

protected void Page_Load(object sender, EventArgs e) {
    var tb = GetListItems(this);
}

[WebMethod]
public static List<CustomListControl.IListItem> GetListItems(System.Web.UI.Page page)
{
    var c = null;    

    if (page != null)
    {
        c = page.FindControl("myList");
    }
    return c;
}
Joel Etherton