Main image
2nd July
2010
written by Chris

User controls are the source of a lot of headaches in C#. They have two major issues that tend to drive programmers a little mad. The first is that they don’t play nicely with the ViewState. Particularly once users start to nest and reorder user controls, the ViewState model (much of which is based on position within the page) starts to break down. In many cases programmers circumvent this little nightmare by simply disabling the ViewState on some controls.

The second issue is that user controls are in their own scope and don’t have immediate access to the rest of the page. That is both a blessing and a curse; good control design means that the controls should be fairly independent of each other but a more pragmatic developer will also note that user controls exist primarily so that numerous copies of the same thing can be easily created and that making entirely self contained controls leads to a lot of unnecessary duplication.

Fortunately there are workarounds for both of these issues.

Regardless of view state, a user control can pass information and therefore trigger events properly using the ASP framework by means of some elaborate JavaScript trickery. In this example, I am using JQuery and JavaScript to allow a click event inside a ViewStateless user control to set the value of a text box and click a button outside of the control, thereby triggering an event within the ASP framework.

$(JQueryObjectForMyUserControl).find(".clickableElement")
.unbind("click").click(function() {
        var clickHandler = $(this).parents(".OuterBound").find(".ClickHandler");
        //I'm replacing the underscores with dollar signs here because that is what ASP expects to find internally
        var argument = $(this).find("a").attr("id").replace(/_/g, "$");
        clickHandler.find(".ClickHandlerArgument").val(argument);
        clickHandler.find(".ClickHandlerLinkButton").click();
    });

Getting around the scope restriction requires a great deal less insanity. For example, my user controls have to be able to activate a modal overlay and dialog box. I could put the code for that inside each user control but that would be a lot of code bloat. Instead, I have the dialog in one place on my page and allow the controls to set its values and activate it.

Page page = this.Page;
ModalPopupExtender ModalPopupExtenderLockedDialog = (ModalPopupExtender)page.FindControl("ModalPopupExtenderLockedDialog");
Label LabelMessage = (Label)page.FindControl("LabelMessage");
ModalPopupExtenderLockedDialog.Show();
LabelMessage.Text = "Hello World!";

Getting to properties is only a little harder. If you need to get to the properties of your page you need only cast this.Page appropriately.

Comments are closed.