24

Web ユーザー コントロールのプロパティとして int 配列があります。可能であれば、次の構文を使用してそのプロパティをインラインで設定したいと思います。

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

これは、実際の int 配列を期待するため、実行時に失敗しますが、代わりに文字列が渡されます。文字列を作成myintarrayしてセッターで解析することはできますが、もっとエレガントな解決策があるかどうか疑問に思っていました。

4

11 に答える 11

20

型コンバーターを実装します。これが1つです。警告:迅速で汚い、本番用ではないなど:

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; }
}
于 2008-09-22T19:52:25.260 に答える
6

@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();
    }
}
于 2008-09-22T20:45:57.987 に答える
5

論理的で、より拡張可能なアプローチは、asp:リストコントロールからページを取得することだと私には思えます。

<uc1:mycontrol runat="server">
    <uc1:myintparam>1</uc1:myintparam>
    <uc1:myintparam>2</uc1:myintparam>
    <uc1:myintparam>3</uc1:myintparam>
</uc1:mycontrol>
于 2008-09-22T19:26:56.833 に答える
4

素晴らしいスニペット@mathieu。longを変換するためにこれを使用する必要がありましたが、LongArrayConverterを作成するのではなく、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();
    }
}

このバージョンは、文字列から変換可能なすべてのタイプで機能するはずです。

[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; }
于 2012-02-22T16:57:02.137 に答える
2

タイプコンバーターを調べてみましたか?このページは一見の価値があります: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属性でプロパティを装飾すると、機能する可能性があります。

于 2008-09-22T19:23:59.460 に答える
2

次のようなこともできます。

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>
于 2009-11-23T11:45:34.880 に答える
1

リストを作成する子要素を追加するには、コントロールを特定の方法で設定する必要があります。

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

上記のアクションは、子要素が含まれるプロパティの名前です。他に何もテストしていないため、ArrayListを使用します。

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

contorlが初期化されると、子要素の値が含まれます。あなたがintを保持するだけのミニクラスを作ることができるもの。

于 2008-09-22T19:43:22.677 に答える
0

ユーザーコントロールでListプロパティを作成するために必要なリストを使用して、Billが話していたことを実行します。次に、Billが説明したように実装できます。

于 2008-09-22T19:30:59.287 に答える
0

aspx内のページイベントに次のようなものを追加できます。

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
    YourUserControlID.myintarray = new Int32[] { 1, 2, 3 };
}
</script>
于 2008-09-22T19:38:36.353 に答える
0

int 配列と文字列のデータ型を変換する型コンバーター クラスを実装できます。次に、int 配列プロパティを TypeConverterAttribute で装飾し、実装したクラスを指定します。その後、Visual Studio は、プロパティの型変換に型コンバーターを使用します。

于 2008-09-22T20:07:03.413 に答える
0

親コントロールの 1 つで DataBinding を使用する場合は、DataBinding 式を使用できます。

<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} %>" />
于 2020-08-24T14:26:23.350 に答える