Data Browser - Viewing Site  Sector 23 Code Bank Logged in as:  Guest  




           


.NET Generate Local Resource adds extra properties
.NET "Generate Local Resource" command was adding a lot of empty/default property values to my custom server controls.
For example, <my:Text runat="server"/> became <my:Text runat="server" MyProperty="SingleLine" MyOtherProperty=""/>, even though I did not want those set in the UI.

Cause:
.NET is filling in properties automatically where the property of the object did not match the default property for the type.

Solution 1:
Set the "DefaultValue" meta data on the property so that it matches the actual default value in the control. For example, if MyProperty is initialized to TextBoxMode.SingleLine, add:

[DefaultValue(typeof(TextBoxMode), "SingleLine")]
public TextBoxMode MyProperty
{
etc..
}

Or if your property is a string, and it defaults to 'null' instead of the empty string add:
[DefaultValue(null)]
public string MyOtherProperty
{ etc.. }

Or if your property is a short, and it defaults to (short)0 instead of (int)0, add:
[DefaultValue(typeof(short), "0")]
public override short TabIndex
{etc..}

Solution 2:
If you have a dynamic property with changing value (such as dependent on current time), you cannot use Solution 1, as the Default is not known. In this case you could prevent it from ever appearing in any designer, and only set it in code behind:

//Hide from Designer Property Grid
[Browsable(false)]
// Hide from VS.NET Code Editor IntelliSense
[EditorBrowsable(EditorBrowsableState.Never)]
// Not Serialized in Designer Source code "HTML view"
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

Solution 3:
Similar to 2, but you can cause the control to leave it's values as the default in the code when in designer by using this check:

if (System.ComponentModel.LicenseManager.CurrentContext.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
return; // don't parse data in design mode or it throws an error; can't use DesignMode flag as it's not set in constructor

Another issue - what if the html tag itself gets rewritten? For example, consider:
public class CloseButton : Control
{
public CloseButton()
{
this.Controls.Add(new Button())
//etc...
}
} // class

When you run generate local resource on this, it replaces "<ns:CloseButton runat="server"/> with "<asp:Button runat="server" />"

The solution is to add metadata to the class itself telling the designer NOT to parse the control at design time.
Add to the class the following tags:
[ParseChildren(true)]
[PersistChildren(false)]
public class CloseButton : Control

And now it won't mess up your HTML.

You will notice that the WebControl class already has these whereas Control doesn't. So depending on what you are inheriting from, you may have to add them yourself. (Anything that doesn't inherit from WebControl).

Created By: amos 5/9/2013 12:27:00 PM
Updated: 9/9/2014 5:48:51 PM