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