How to update design-time UserControl interface based on property value

asp.netdesigneruser-controlsvisual-studio-2008webforms

I've created a UserControl with the following public property:

[Browsable(true)]
public string Text
{
    get { return pnlLookupTable.GroupingText; }
    set { pnlLookupTable.GroupingText = value; }
}

pnlLookupTable is, as you may have guessed, a Panel control. I can change the value of the Text property in the Properties window and it's reflected in the markup like it should be. However, the design view of the UserControl inside a page does not show updated GroupingText for the Panel. How can I get this to happen?

EDIT:

By request, here is the entire class to which that property belongs. You can see there's nothing special going on:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class LookupTable : System.Web.UI.UserControl
{
    [Browsable(true)]
    public string Text
    {
        get { return pnlLookupTable.GroupingText; }
        set { pnlLookupTable.GroupingText = value; }
    }
}

And here's the relevant part of the .ascx file:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="LookupTable.ascx.cs" Inherits="LookupTable" %>
<asp:Panel ID="pnlLookupTable" runat="server" GroupingText="Lookup Table">
    <%-- Irrelevant content here. --%>
</asp:Panel>

I have changed some identifiers and other trivial things to protect the proprietary nature of the code.

I should also reiterate that I'm looking at a Web form in design mode that has my control added, and I'm changing the Text property. I want to see the change to the Panel's GroupingText visually in the designer.

Best Solution

I'd have to think back a bit to the UserControlDesigner code...

Short story: I don't think it's possible.

And here's the long story:

From what I recall, User Controls located in ASCX files are never run in the designer. That is, the code inside the ASCX or ASCX.CS file is never compiled or run in Visual Studio. This is to prevent memory leaks caused by the fact that in the CLR you cannot unload assemblies that you have loaded. In order to run the code in your User Control, Visual Studio would have to compile your ASCX into a DLL, then load it, and then run the code. Every time you make a change to the ASCX, it would have to perform this operation again. Every time this operation happens more memory will be consumed by the additionally loaded DLL generated from your ASCX.

Because of this limitation in the CLR the User Control designer doesn't actually compile or run the ASCX file. Instead, it parses the ASCX file and looks for controls inside it and it loads those controls instead. For each control it finds in the ASCX file it will create the associated control designer and render that control's design time HTML.

There are a couple of ways to work around this:

  1. Instead of using an ASCX user control you can write a regular custom control that derives from Control and the code is written in a CS or VB file.
  2. Compile the ASCX into a DLL. David Ebbo wrote a blog post on how to do this.

The reason that these two solutions should work is that they both involve having the code compiled into a DLL. The idea is that the DLL doesn't change very often so it is safe for Visual Studio to load the DLL without risk of having to reload it for each time the DLL changes (and leak memory).

Related Question