Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Properly overriding the Width Property of Web Control?


:P
On this page:

Ok, here’s a stupid question… I keep running into this from time to time and I waste a few minutes on this every time I do and I’ve never really resolved this properly.

 

If I have a control that inherits say from a Panel control (which basically generates a <div>) and I want to override the width to a different default value I do:

 

/// <summary>

/// Override default Width

/// </summary>          

[DefaultValue(typeof(Unit),"250px")]

public override Unit Width

{

    get { return base.Width; }

    set { base.Width = value; }

}

 

This works for showing the control with a width of 250px. Fine. But now if I go in make a change to the width in the designer, then tell the designer to reset the value it sets the designer value back to 250px but it generates a blank into the HTML markup:

 

<ww:wwDbResourceControl runat="server" ID="dbResourceManager"

                        CssClass="ErrorDisplay"

                        style="padding:10px">

 

Notice no width of 250. So at this point the control renders a full width <div> that spans the width of the form because it’s essentially rendering without a width at all, which is the base behavior.

 

So I tried override and new, but both show the same behavior. I also tried this:

 

/// <summary>

/// Override default Width

/// </summary>          

[DefaultValue(typeof(Unit),"250px")]

public override Unit Width

{

    get { return base.Width; }

    set

    {

        if (value == Unit.Empty)

            value = Unit.Pixel(250);

 

        base.Width = value;

    }

}

 

Which gives some really crazy behavior. Now when setting the empty value the control shows at 250 pixels but when I set to 250 pixels (or Reset in the designer) the control renders full width again.


I also tried using my own property and not calling back into base.Width, but that’s not really a good idea either I suspect and that doesn’t any more reliably because apparently the base behavior looks at the base value even if the override exists higher up the chain…

 

The only way I can get close to the desired behavior is to skip putting a [DefaultValue()] attribute on the control. When I do that the control always renders the tag and then value is properly reflected. But this shouldn’t really be necessary.

 

Question is how do I properly subclass the control to get the width to properly render at 250px when reset?

Posted in ASP.NET  

The Voices of Reason


 

Atanas Korchev
October 15, 2006

# re: Properly overriding the Width Property of Web Control?

Setting the DefaultValue attribute is not enough. It simply tells the designer which is the default (not to be serialized) value. However at runtime the DefaultValue attribute does nothing. You still rely on the base getter implementation which returns Unit.Empty when the value is not set. In a word I think you should override the getter as well:

[DefaultValue(typeof(Unit),"250px")]
public override Unit Width
{
    get
    {
       if (base.Width == Unit.Empty)
       {
          return Unit.Pixel(250);
       }
       return base.Width;
    }
    set 
    {
        if (value == Unit.Empty)

            value = Unit.Pixel(250);
        base.Width = value; 
     }
}

Rick Strahl
October 15, 2006

# re: Properly overriding the Width Property of Web Control?

Thanks Atanas, yes this would probably work...

However <g>... this doesn't solve the problem completely. With that code in place you can't have the Width blank (ie. default div sizing). Not a problem in this scenario, because it will always end up some fixed width, but if you needed a blank value too this wouldn't work.

Removing DefaultValue completely also doesn't work quite right - the behavior then is correct, but the starting value is wrong (it should be 250px). I suppose that could be overridden in the constructor though. That's probably the best way to handle this: Override the constructor so you get a default value, but let the Resetting be handled by the base. That way the default behavior is not affected.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024