自定义asp.net控件的样式属性在设置时抛出异常

时间:2011-11-23 18:11:16

标签: c# asp.net

我编写了继承自System.Web.UI.Control的自定义控件。我添加了Style属性,如下所示:

public class MyControl : Control
{
    public CssStyleCollection Style
    {
        get { return ViewState["Style"] as CssStyleCollection; }
        set { ViewState["Style"] = value; }
    }
}

我用以下方式

<custom:MyControl runat="server" Style="float: left; padding: 2px 4px;" ... />

当我尝试加载页面时,收到以下异常:

  

无法创建'System.Web.UI.CssStyleCollection'类型的对象   从它的字符串表示'float:left;填充:2px 4px;'为了   '风格'属性。

我想我应该为属性或类似物添加TypeConverter属性,但我在System.Web.UI命名空间中找不到合适的属性。我还搜索了谷歌,并没有太多关于这个问题的信息。 我知道如果我延长WebControl这会有效,但我更喜欢处理Control的解决方案。

2 个答案:

答案 0 :(得分:3)

当您向ASP.NET控件添加样式时,您应该能够使用标准style属性。该属性可能会从智能感知中隐藏,但它是一个可接受的HTML属性,因此它仍然可以工作:

<asp:TextBox ID="TextBox1" runat="server" style="font-weight:bold;" />

在幕后,将解析style属性,并将属性加载到Styles集合中:

string weight = TextBox1.Styles["font-weight"]; //== "bold"

答案 1 :(得分:1)

这就是我解决问题的方法,但并不完美:

  1. 使自定义控件的Style属性为字符串而不是CssStyleCollection。
  2. 创建一个CssStyleCollection类型的私有实例变量。
  3. 使用反射使用其私有构造函数创建CssStyleCollection的实例。
  4. 设置并获取私有CssStyleCollection的“Value”属性。这是一个字符串,将在您设置时进行解析。
  5. 覆盖渲染并使用CssStyleCollection实例的“Value”属性。
    private CssStyleCollection iStyle;
    public string Style 
    {
        get
        {
            if (iStyle == null)
            {
                iStyle = CreateStyle(ViewState);                    
            }
            return iStyle.Value;
        }
        set
        {
            if (iStyle == null)
            {
                iStyle = CreateStyle(ViewState);                    
            }
            //Could add differnet logic here
            iStyle.Value += value == null ? string.Empty : value;
        }
    }

    private static CssStyleCollection CreateStyle(StateBag aViewState)
    {
        var tType = typeof(CssStyleCollection);
        var tConstructors = tType.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
        foreach (var tConstructor in tConstructors)
        {
            var tArgs = tConstructor.GetParameters();
            if (tArgs.Length == 1 && tArgs[0].ParameterType == typeof(StateBag))
            {
                return (CssStyleCollection)tConstructor.Invoke(new object[] { aViewState });
            }
        }
        return null;
    }

    protected override void Render(HtmlTextWriter aOutput)
    {
        aOutput.AddAttribute("style", Style);

        aOutput.RenderBeginTag("span");
        foreach (Control tControl in this.Controls)
        {
            tControl.RenderControl(aOutput);
        }
        aOutput.RenderEndTag();            
    }