Search code examples
c#asp.nethtmlgenericcontrol

How do I cast an HtmlGenericControl as a WebControl?


... I am trying to dynamically add or remove classes to my ASP controls using this code (which I found via my great pair-programming friend who shall be known as 'Mr G')

public static class WebHelper
{
    public static void AddCssClass(this WebControl control, string cssClass) {
        List<string> classes;
        if (!string.IsNullOrWhiteSpace(control.CssClass)) 
        {
            classes = control.CssClass.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            if (!classes.Contains(cssClass))
                classes.Add(cssClass);
        }
        else
        {
            classes = new List<string> { cssClass };
        }
        control.CssClass = string.Join(" ", classes.ToArray());
    }

    public static void RemoveCssClass(this WebControl control, string cssClass)
    {
        List<string> classes = new List<string>();
        if (!string.IsNullOrWhiteSpace(control.CssClass))
        {
            classes = control.CssClass.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
        }
        classes.Remove(cssClass);
        control.CssClass = string.Join(" ", classes.ToArray());
    }
}

Unfortunately I can't find a way to pass my HtmlGenericControls to them... I've tried the obvious:

WebControl test1 = (WebControl)Page.FindControl("divcontent");
WebHelper.AddCssClass(test1, centredClass);

But I get: System.InvalidCastException: Unable to cast object of type 'System.Web.UI.HtmlControls.HtmlGenericControl' to type 'System.Web.UI.WebControls.WebControl'.

I'm still relatively inexperienced at C#, Visual Studio etc as my background is Ye Olde Pick BASIC, so please explain simply how I either cast my control, or amend the code so it will achieve the end goal of being able to add or remove classes without losing any existing ones.

Many thanks! Ross


Solution

  • You're using your friends class wrong. Methods in your WebHelper are extension methods, so it should look like this:

    WebControl test1 = (WebControl)Page.FindControl("divcontent");
    test1.AddCssClass("something");
    

    (verified that it works). Make sure your control derives from WebControl and it has runat="server" set.

    Edit: modified WebHelper to support HtmlControls as well

    public static class WebHelper
    {
        public static void AddCssClass(this HtmlControl control, string cssClass)
        {
            List<string> classes;
            if (!string.IsNullOrWhiteSpace(control.Attributes["class"]))
            {
                classes = control.Attributes["class"].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                if (!classes.Contains(cssClass))
                    classes.Add(cssClass);
            }
            else
            {
                classes = new List<string> { cssClass };
            }
            control.Attributes["class"] = string.Join(" ", classes.ToArray());
        }
    
        public static void RemoveCssClass(this HtmlControl control, string cssClass)
        {
            List<string> classes = new List<string>();
            if (!string.IsNullOrWhiteSpace(control.Attributes["class"]))
            {
                classes = control.Attributes["class"].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            }
            classes.Remove(cssClass);
            control.Attributes["class"] = string.Join(" ", classes.ToArray());
        }
    
        public static void AddCssClass(this WebControl control, string cssClass)
        {
            List<string> classes;
            if (!string.IsNullOrWhiteSpace(control.CssClass))
            {
                classes = control.CssClass.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                if (!classes.Contains(cssClass))
                    classes.Add(cssClass);
            }
            else
            {
                classes = new List<string> { cssClass };
            }
            control.CssClass = string.Join(" ", classes.ToArray());
        }
    
        public static void RemoveCssClass(this WebControl control, string cssClass)
        {
            List<string> classes = new List<string>();
            if (!string.IsNullOrWhiteSpace(control.CssClass))
            {
                classes = control.CssClass.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            }
            classes.Remove(cssClass);
            control.CssClass = string.Join(" ", classes.ToArray());
        }
    }
    

    Feel free to modify the code as needed. Everything remained the same, just added extension methods for HtmlControl, because if you want to modify a class of HtmlControl, you need to work with control.Attributes["class"], as there is no CssClass attribute. Hope it helps!