1

I want the constructor of my WebControl to be able to access the value of IsSpecial (from the HTML). However, it's always false. I assume that it's false in the constructor because it doesn't read the value until after the constructor method is over. Is there a way to have it so it knows the correct value of IsSpecial in the constructor?

C#:

[DefaultProperty("Text")]
[ToolboxData("<{0}:WebControlExample runat=server></{0}:WebControlExample>")]
public class WebControlExample: WebControl, INamingContainer
{
    private readonly int[] goodies;

    public WebControlExample()
    {
        if (this.isSpecial)
        {
            goodies = new int[24];
        }
        else
        {
            //always reaches here
            goodies = new int[48];
        }
    }

    private bool isSpecial= false;
    public bool IsSpecial
    {
        set
        {
            this.isSpecial= value;
        }
    }
}

HTML:

<xyz:WebControlExamplerunat="server" id="webControlExample" IsSpecial="true" />

2 Answers2

1

The value entered in the markup for the IsSpecial property won't have been assigned to the property until after the constructor is run. Think about it,.. you're expecting code equivalent to the following:

WebControlExample webControlExample = null;
webControlExample.IsSpecial = true;
webControlExample = new WebControlExample();

What's actually happening (simplified!) is:

WebControlExample webControlExample = null;
webControlExample = new WebControlExample();
webControlExample.IsSpecial = true;

There is no way to affect this for the constructor, and you probably shouldn't be doing much of anything in the constructor for a WebControl anyway.

Rob
  • 45,296
  • 24
  • 122
  • 150
  • I figured this was the case, but is there no work around? Is there a way I can pass a parameter to the constructor from the HTML side? – But I'm Not A Wrapper Class Apr 01 '15 at 14:48
  • @CyberneticTwerkGuruOrc, I've never seen it done and aren't familiar with any way of writing custom controls that the asp.net compiler will call a custom ctor on, I'm afraid. Is there a reason the work has to be done in the ctor and can't be done at another stage of the controls lifecycle? – Rob Apr 01 '15 at 14:53
  • The web control does a lot of work and the `readonly` variable must stay `readonly`. This means I cannot `extend` either. I want to make a small variation on the web control based on this one parameter. I could just make a whole new class and move common code to a shared class, but I thought that was way too much work for something that I believe was a small change. – But I'm Not A Wrapper Class Apr 01 '15 at 15:02
  • @CyberneticTwerkGuruOrc Why does it have to be `readonly` if it's `private`? Are you afraid other code is going to reassign the array? – D Stanley Apr 01 '15 at 16:27
1

This isn't a great solution, but if you have to have a readonly array, you could have two readonly arrays and wrap them in an accessor:

[DefaultProperty("Text")]
[ToolboxData("<{0}:WebControlExample runat=server></{0}:WebControlExample>")]
public class WebControlExample: WebControl, INamingContainer
{
    private readonly int[] goodies = new int[48];
    private readonly int[] goodiesSpecial = new int[24];

    private bool isSpecial= false;
    public bool IsSpecial
    {
        set
        {
            this.isSpecial= value;
        }
    }

    private int[] Goodies
    {
         get {return isSpecial ? goodiesSpecial : goodies;}
    }
}

But you haven't stated 1. Why you need two different-sized arrays or 2. What you're doing with them.

D Stanley
  • 149,601
  • 11
  • 178
  • 240