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

本文关键字:设置 抛出异常 属性 样式 asp net 控件 自定义 | 更新日期: 2023-09-27 18:15:37

我编写了继承自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的解决方案。

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

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

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

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

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

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

    让你的自定义控件的Style属性是一个字符串,而不是一个CssStyleCollection。创建一个CssStyleCollection类型的私有实例变量。
  1. 使用反射创建CssStyleCollection的私有构造函数实例。
  2. 设置并获取私有CssStyleCollection的"Value"属性。这是一个字符串,当您设置它时将被解析。
  3. 覆盖渲染并使用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();            
    }