在 Web 用户控件中传递 int 数组作为参数

发布于 2024-07-06 01:40:55 字数 249 浏览 4 评论 0原文

我有一个 int 数组作为 Web 用户控件的属性。 如果可能的话,我想使用以下语法来内联设置该属性:

<uc1:mycontrol runat="server" myintarray="1,2,3" />

这将在运行时失败,因为它将期望一个实际的 int 数组,但正在传递一个字符串。 我可以将 myintarray 制作为字符串并在 setter 中解析它,但我想知道是否有更优雅的解决方案。

I have an int array as a property of a Web User Control. I'd like to set that property inline if possible using the following syntax:

<uc1:mycontrol runat="server" myintarray="1,2,3" />

This will fail at runtime because it will be expecting an actual int array, but a string is being passed instead. I can make myintarray a string and parse it in the setter, but I was wondering if there was a more elegant solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

层林尽染 2024-07-13 01:40:56

您可以向 aspx 内的页面事件添加如下内容:

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
    YourUserControlID.myintarray = new Int32[] { 1, 2, 3 };
}
</script>

You could add to the page events inside the aspx something like this:

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
    YourUserControlID.myintarray = new Int32[] { 1, 2, 3 };
}
</script>
ゞ记忆︶ㄣ 2024-07-13 01:40:56

您可以实现一个类型转换器类,在 int 数组和字符串数据类型之间进行转换。
然后使用 TypeConverterAttribute 修饰 int 数组属性,指定您实现的类。 然后,Visual Studio 将使用您的类型转换器对您的属性进行类型转换。

You can implement a type converter class that converts between int array and string data types.
Then decorate your int array property with the TypeConverterAttribute, specifying the class that you implemented. Visual Studio will then use your type converter for type conversions on your property.

清秋悲枫 2024-07-13 01:40:56

如果您在父控件之一上使用数据绑定,则可以使用数据绑定表达式:

<uc1:mycontrol runat="server" myintarray="<%# new [] {1, 2, 3} %>" />

使用自定义表达式生成器,您可以执行类似的操作。 表达式生成器:

[ExpressionPrefix("Code")]
public class CodeExpressionBuilder : ExpressionBuilder
{
    public override CodeExpression GetCodeExpression(System.Web.UI.BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
    {
        return new CodeSnippetExpression(entry.Expression.Trim());
    }
}

用法:

<uc1:mycontrol runat="server" myintarray="<%$ Code: new [] {1, 2, 3} %>" />

If you use DataBinding on one of the parent Controls, you can use a DataBinding Expression:

<uc1:mycontrol runat="server" myintarray="<%# new [] {1, 2, 3} %>" />

With a custom expression builder, you can do something similar. The expression builder:

[ExpressionPrefix("Code")]
public class CodeExpressionBuilder : ExpressionBuilder
{
    public override CodeExpression GetCodeExpression(System.Web.UI.BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
    {
        return new CodeSnippetExpression(entry.Expression.Trim());
    }
}

Usage:

<uc1:mycontrol runat="server" myintarray="<%$ Code: new [] {1, 2, 3} %>" />
江城子 2024-07-13 01:40:55

@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();
    }
}

@mathieu, thanks so much for your code. I modified it somewhat in order to compile:

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();
    }
}
耳钉梦 2024-07-13 01:40:55

在我看来,逻辑且更可扩展的方法是从 asp: 列表控件中获取页面:

<uc1:mycontrol runat="server">
    <uc1:myintparam>1</uc1:myintparam>
    <uc1:myintparam>2</uc1:myintparam>
    <uc1:myintparam>3</uc1:myintparam>
</uc1:mycontrol>

Seems to me that the logical—and more extensible—approach is to take a page from the asp: list controls:

<uc1:mycontrol runat="server">
    <uc1:myintparam>1</uc1:myintparam>
    <uc1:myintparam>2</uc1:myintparam>
    <uc1:myintparam>3</uc1:myintparam>
</uc1:mycontrol>
歌枕肩 2024-07-13 01:40:55

很棒的片段@mathieu。 我需要使用它来转换 long,但我没有制作 LongArrayConverter,而是编写了一个使用泛型的版本。

public class ArrayConverter<T> : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string val = value as string;
        if (string.IsNullOrEmpty(val))
            return new T[0];

        string[] vals = val.Split(',');
        List<T> items = new List<T>();
        Type type = typeof(T);
        foreach (string s in vals)
        {
            T item = (T)Convert.ChangeType(s, type);
            items.Add(item);
        }
        return items.ToArray();
    }
}

此版本应该适用于任何可从字符串转换的类型。

[TypeConverter(typeof(ArrayConverter<int>))]
public int[] Ints { get; set; }

[TypeConverter(typeof(ArrayConverter<long>))]
public long[] Longs { get; set; }

[TypeConverter(typeof(ArrayConverter<DateTime))]
public DateTime[] DateTimes { get; set; }

Great snippet @mathieu. I needed to use this for converting longs, but rather than making a LongArrayConverter, I wrote up a version that uses Generics.

public class ArrayConverter<T> : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string val = value as string;
        if (string.IsNullOrEmpty(val))
            return new T[0];

        string[] vals = val.Split(',');
        List<T> items = new List<T>();
        Type type = typeof(T);
        foreach (string s in vals)
        {
            T item = (T)Convert.ChangeType(s, type);
            items.Add(item);
        }
        return items.ToArray();
    }
}

This version should work with any type that is convertible from string.

[TypeConverter(typeof(ArrayConverter<int>))]
public int[] Ints { get; set; }

[TypeConverter(typeof(ArrayConverter<long>))]
public long[] Longs { get; set; }

[TypeConverter(typeof(ArrayConverter<DateTime))]
public DateTime[] DateTimes { get; set; }
鯉魚旗 2024-07-13 01:40:55

您是否尝试过研究类型转换器? 此页面看起来值得一看: 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 属性装饰属性,可能会起作用。

Have you tried looking into Type Converters? This page looks worth a look: http://www.codeguru.com/columns/VB/article.php/c6529/

Also, Spring.Net seems to have a StringArrayConverter (http://www.springframework.net/doc-latest/reference/html/objects-misc.html - section 6.4) which, if you can feed it to ASP.net by decorating the property with a TypeConverter attribute, might work..

浮萍、无处依 2024-07-13 01:40:55

你也可以做这样的事情:

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>

You could also do something like this:

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>();
        }
    }
}

which will result in:

<xx:CustomUserControl  runat="server">
  <Values>
            <xx:ArrayItem Value="1" />
  </Values>
</xx:CustomUserControl>
放血 2024-07-13 01:40:55

要添加组成列表的子元素,您需要以某种方式设置控件:

[ParseChildren(true, "Actions")]
[PersistChildren(false)]
[ToolboxData("<{0}:PageActionManager runat=\"server\" ></PageActionManager>")]
[NonVisualControl]
public class PageActionManager : Control
{

上面的操作是子元素所在的 cproperty 的名称。我使用 ArrayList,因为我没有用它测试任何其他内容。 :

        private ArrayList _actions = new ArrayList();
    public ArrayList Actions
    {
        get
        {
            return _actions;
        }
    }

当你的控件初始化时,它将具有子元素的值。 您可以制作一个仅包含整数的迷你课程。

To add child elements that make your list you need to have your control setup a certain way:

[ParseChildren(true, "Actions")]
[PersistChildren(false)]
[ToolboxData("<{0}:PageActionManager runat=\"server\" ></PageActionManager>")]
[NonVisualControl]
public class PageActionManager : Control
{

The Actions above is the name of the cproperty the child elements will be in. I use an ArrayList, as I have not testing anything else with it.:

        private ArrayList _actions = new ArrayList();
    public ArrayList Actions
    {
        get
        {
            return _actions;
        }
    }

when your contorl is initialized it will have the values of the child elements. Those you can make a mini class that just holds ints.

小嗲 2024-07-13 01:40:55

执行 Bill 所说的列表操作,只需在用户控件上创建一个 List 属性即可。 然后你就可以按照 Bill 的描述来实现它。

Do do what Bill was talking about with the list you just need to create a List property on your user control. Then you can implement it as Bill described.

凉风有信 2024-07-13 01:40:55

实现一个类型转换器,这里是一个,警告:快速&肮脏,不适用于生产用途等:

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; }
}

Implement a type converter, here is one, warning : quick&dirty, not for production use, etc :

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();
    }
}

and tag the property of your control :

private int[] ints;
[TypeConverter(typeof(IntsConverter))]
public int[] Ints
{
    get { return this.ints; }
    set { this.ints = value; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文