تمرير مجموعة int كمعلمة في تحكم مستخدم الويب

StackOverflow https://stackoverflow.com/questions/116797

  •  02-07-2019
  •  | 
  •  

سؤال

لدي صفيف int كخاصية لعنصر تحكم مستخدم الويب.أرغب في تعيين هذه الخاصية في السطر إن أمكن باستخدام بناء الجملة التالي:

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

سيفشل هذا في وقت التشغيل لأنه يتوقع مصفوفة int فعلية، ولكن يتم تمرير سلسلة بدلاً من ذلك.أنا أستطيع صنع myintarray سلسلة وتحليلها في أداة الضبط، لكنني كنت أتساءل عما إذا كان هناك حل أكثر أناقة.

هل كانت مفيدة؟

المحلول

قم بتنفيذ محول النوع، إليك تحذير:سريع وقذر، وليس للاستخدام الإنتاجي، وما إلى ذلك:

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

نصائح أخرى

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

يبدو لي أن النهج المنطقي - والأكثر قابلية للتوسعة - هو أخذ صفحة من asp: ضوابط القائمة:

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

مقتطف رائع @mathieu.كنت بحاجة لاستخدام هذا لتحويل الأطوال، ولكن بدلاً من إنشاء 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; }

هل حاولت البحث في محولات النوع؟تبدو هذه الصفحة تستحق المشاهدة: 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، فقد يعمل..

يمكنك أيضًا القيام بشيء مثل هذا:

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>

لإضافة عناصر فرعية تشكل قائمتك، يجب أن يتم إعداد عنصر التحكم الخاص بك بطريقة معينة:

[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 الخاص بك، سيكون لديه قيم العناصر الفرعية.تلك التي يمكنك إنشاء فصل دراسي صغير يحتوي فقط على ints.

افعل ما كان بيل يتحدث عنه بالقائمة التي تحتاجها فقط لإنشاء خاصية قائمة على عنصر تحكم المستخدم الخاص بك.ثم يمكنك تنفيذه كما وصف بيل.

يمكنك إضافة شيء من هذا القبيل إلى أحداث الصفحة داخل aspx:

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

يمكنك تنفيذ فئة محول النوع التي تقوم بالتحويل بين أنواع بيانات الصفيف وسلسلة int.ثم قم بتزيين خاصية الصفيف int الخاصة بك باستخدام TypeConverterAttribute، مع تحديد الفئة التي قمت بتنفيذها.سيستخدم Visual Studio بعد ذلك محول النوع الخاص بك لتحويلات النوع على الممتلكات الخاصة بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top