将int数组作为参数传递给Web用户控件
我有一个int数组作为Web用户控件的属性。我想尽可能使用以下语法内联设置该属性:
<uc1:mycontrol runat="server" myintarray="1,2,3" />
这将在运行时失败,因为它将期望使用实际的int数组,但是将传递字符串。我可以将" myintarray"设置为字符串,然后在设置器中对其进行解析,但是我想知道是否有更优雅的解决方案。
解决方案
我们是否尝试过研究类型转换器?该页面值得一看:http://www.codeguru.com/columns/VB/article.php/c6529/
另外,Spring.Net似乎有一个StringArrayConverter(http://www.springframework.net/doc-latest/reference/html/objects-misc.html第6.4节),如果可以通过修饰将其提供给ASP.net,具有TypeConverter属性的属性可能会起作用。
在我看来,合理且更可扩展的方法是从" asp:"列表控件中获取一个页面:
<uc1:mycontrol runat="server">
<uc1:myintparam>1</uc1:myintparam>
<uc1:myintparam>2</uc1:myintparam>
<uc1:myintparam>3</uc1:myintparam>
</uc1:mycontrol>
执行Bill所谈论的列表操作,我们只需要在用户控件上创建List属性即可。然后,我们可以按照Bill所述实施它。
我们可以在aspx内的页面事件中添加以下内容:
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
YourUserControlID.myintarray = new Int32[] { 1, 2, 3 };
}
</script>
要添加构成列表的子元素,我们需要以某种方式设置控件:
[ParseChildren(true, "Actions")]
[PersistChildren(false)]
[ToolboxData("<{0}:PageActionManager runat=\"server\" ></PageActionManager>")]
[NonVisualControl]
public class PageActionManager : Control
{
上面的Actions是子元素将所在的属性的名称。我使用ArrayList,因为我没有对其进行任何其他测试。
private ArrayList _actions = new ArrayList();
public ArrayList Actions
{
get
{
return _actions;
}
}
当控制被初始化时,它将具有子元素的值。那些我们可以建立一个仅容纳int的迷你类。
实现一个类型转换器,这是一个,警告:快速,肮脏,不用于生产用途等:
public class IntArrayConverter : System.ComponentModel.TypeConverter
{
public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
string val = value as string;
string[] vals = val.Split(',');
System.Collections.Generic.List<int> ints = new System.Collections.Generic.List<int>();
foreach (string s in vals)
ints.Add(Convert.ToInt32(s));
return ints.ToArray();
}
}
并标记控件的属性:
private int[] ints;
[TypeConverter(typeof(IntsConverter))]
public int[] Ints
{
get { return this.ints; }
set { this.ints = value; }
}
我们可以实现在int数组和字符串数据类型之间进行转换的类型转换器类。
然后,使用TypeConverterAttribute装饰int数组属性,并指定我们实现的类。然后,Visual Studio将使用类型转换器对属性进行类型转换。
@mathieu,非常感谢代码。我对其进行了一些修改以进行编译:
public class IntArrayConverter : System.ComponentModel.TypeConverter
{
public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
string val = value as string;
string[] vals = val.Split(',');
System.Collections.Generic.List<int> ints = new System.Collections.Generic.List<int>();
foreach (string s in vals)
ints.Add(Convert.ToInt32(s));
return ints.ToArray();
}
}
我们还可以执行以下操作:
namespace InternalArray
{
/// <summary>
/// Item for setting value specifically
/// </summary>
public class ArrayItem
{
public int Value { get; set; }
}
public class CustomUserControl : UserControl
{
private List<int> Ints {get {return this.ItemsToList();}
/// <summary>
/// set our values explicitly
/// </summary>
[PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(List<ArrayItem>))]
public List<ArrayItem> Values { get; set; }
/// <summary>
/// Converts our ArrayItem into a List<int>
/// </summary>
/// <returns></returns>
private List<int> ItemsToList()
{
return (from q in this.Values
select q.Value).ToList<int>();
}
}
}
这将导致:
<xx:CustomUserControl runat="server">
<Values>
<xx:ArrayItem Value="1" />
</Values>
</xx:CustomUserControl>

