开发者

ASP.net Webforms, Methods for controlling the ClientID

I'm having a WebForms application which used to mostly run on Postbacks. But now, I'd like to use jQuery more and more, and I would prefer to control the ClientID so that I have a true "#id" selector instead of using "input[id$=myID]".

Now, as I still like to use ASP.net Controls (I need to work with them through CodeBehind), I wonder if there's good alternatives?

The Application in question is running on SharePoint 2007 and 2010, which means a) no way to switch to ASP.net MVC and b) no inline-code inside the .ASPX file, which also means no way to dynamically build the JavaScript using $("<%= MyControl.ClientID %>). (Yes, I know that I can enable Inline Code in the web.config, but I want to avoid that)

One approach right now is to use ASP:Lite开发者_开发技巧rals and completely build the HTML in CodeBehind, but that seems rather clumsy. Any other approach, or am I out of luck?


This is a very common complaint with ASP.NET Web Forms and unfortunately there's not much you can do about it. .NET 4 will give us more control over ClientID generation, but until then it's inevitably going to be a headache.

One option would be to build a JSON string in code behind that contains some of the clientID's you need and use ClientScript.RegisterClientScriptBlock to expose it client-side. It's not pretty but it's better than generating HTML in the code behind.

Code Behind:

String jsonClientIDs = "window.ClientIDs = { " + 
                       "oneControlClientID: '" + oneControl.ClientID + "'," +
                       "twoControlClientID: '" + twoControl.ClientID + "'" +
                       "}";

Page.RegisterClientScriptBlock(GetType(), "ClientIDs", jsonClientIDs, true);

Javascript:

function myFunction()
{
   $(ClientIDs.oneControlClientID).hide();
   $(ClientIDs.twoControlClientID).show();
}


You can override the client ID generation so that ASP.NET doesn't mangle the control names. I posted an example in this thread.

The basic idea is to override the ClientID and UniqueID properties in a descendant class, and then to use that class instead of the built-in ASP.NET control. The provided example demonstrates a textbox, but this applies to any server control.

The great thing about this approach is that it doesn't require passing IDs to the markup. However, it's up to you to make sure you don't generate multiple components with the same ID, ( for instance, in a repeater or listview).

Also: NEVER NEVER NEVER generate your markup in code-behind. Use a listview, repeater or other control. Generating markup in code behind makes for a maintenance nightmare, especially when a designer (someone versed in graphics, HTML and CSS, but not necessarily C#) needs to make changes to your work. Do yourself a favor and keep markup in the ASPX where it belongs, and code in the .cs.

Update partial code sample from referenced thread:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace MyControls
{
    public class Textbox : System.Web.UI.WebControls.TextBox
    {
        public override string ClientID
        {
            get
            {
                return ID;
            }

        }

        public override string UniqueID
        {
            get
            {
                return ID;
            }
        }

    }

    public class Button : System.Web.UI.WebControls.Button
    {

        public override string ClientID
        {
            get
            {
                return ID;
            }

        }

        public override string UniqueID
        {
            get
            {
                return ID;
            }
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜