ويمر الباحث قائمة كمعلمة إلى عنصر تحكم مستخدم ويب

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

  •  05-07-2019
  •  | 
  •  

سؤال

أريد أن تمر الباحث قائمة (قائمة) كما التعريفي خاصية عنصر تحكم مستخدم ويب مثل هذا:

<UC:MyControl runat="server" ModuleIds="1,2,3" />

أنا خلقت TypeConverter للقيام بذلك:

public class IntListConverter : System.ComponentModel.TypeConverter
{
    public override bool CanConvertFrom(
           System.ComponentModel.ITypeDescriptorContext context, 
           Type sourceType)
    {
        if (sourceType == typeof(string)) return true;
        return base.CanConvertFrom(context, sourceType);
    }
    public override object ConvertFrom(
      System.ComponentModel.ITypeDescriptorContext context, 
      System.Globalization.CultureInfo culture, object value)
    {
        if (value is string)
        {
            string[] v = ((string)value).Split(
                new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            List<int> list = new List<int>();
            foreach (string s in vals)
            {
                list.Add(Convert.ToInt32(s));
            }
            return list
        }
        return base.ConvertFrom(context, culture, value);
    }
    public override bool CanConvertTo(ITypeDescriptorContext context,
      Type destinationType)
    {
        if (destinationType == typeof(InstanceDescriptor)) return true;
        return base.CanConvertTo(context, destinationType);
    }
    public override object ConvertTo(ITypeDescriptorContext context,
      System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(InstanceDescriptor) && value is List<int>)
        {
            List<int> list = (List<int>)value;
            ConstructorInfo construcor = typeof(List<int>).GetConstructor(new Type[] { typeof(IEnumerable<int>) });
            InstanceDescriptor id = new InstanceDescriptor(construcor, new object[] { list.ToArray() });
            return id;
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

ثم أضاف السمة العقار:

[TypeConverter(typeof(IntListConverter))]
public List<int> ModuleIds
{
    get { ... }; set { ... };
}

ولكن يمكنني الحصول على هذا الخطأ في وقت التشغيل:

Unable to generate code for a value of type 'System.Collections.Generic.List'1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. This error occurred while trying to generate the property value for ModuleIds.

سؤالي هو مماثلة لتلك الموجودة هنا, لكن الحل لا حل مشكلتي:

تحديث: وجدت الصفحة التي تحل المشكلة الأولى.لقد قمت بتحديث رمز أعلاه إلى إصلاحات.وأضاف الكود هو CanConvertTo و ConvertTo الأساليب.الآن أحصل على خطأ مختلفة.:

Object reference not set to an instance of an object.

هذا الخطأ يبدو غير مباشرة عن شيء في ConvertTo الأسلوب.

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

المحلول

بعد تركيب مصحح أخطاء في كاسيني ، أرى أن null المرجع هي في الحقيقة قادمة من النظام.ويب.تجميع.CodeDomUtility.GenerateExpressionForValue, الذي هو في الأساس محاولة للحصول على تعبير عن int[] مجموعة يمكنك تمرير إلى قائمة منشئ.منذ ليس هناك نوع واصف int[] مجموعة فشل (ويلقي فارغة المرجع في العملية بدلا من "لا يمكن أن تولد تعيين خاصية استثناء" أنه ينبغي).

أنا لا يمكن معرفة بنيت في طريقة الحصول على تسلسل القيمة في قائمة<int>لذلك استخدمت أسلوب ثابت:

class IntListConverter : TypeConverter {
    public static List<int> FromString(string value) {
       return new List<int>(
          value
           .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
           .Select(s => Convert.ToInt32(s))
       );
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
        if (destinationType == typeof(InstanceDescriptor)) {
            List<int> list = (List<int>)value;
            return new InstanceDescriptor(this.GetType().GetMethod("FromString"),
                new object[] { string.Join(",", list.Select(i => i.ToString()).ToArray()) }
            );
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

نصائح أخرى

في حين لا أستطيع أن أقول أن لدي أي خبرة في هذا الخطأ ، مصادر أخرى تشير إلى أنك تحتاج إلى إضافة التحويل إلى نوع InstanceDescriptor.تحقق من:

http://weblogs.asp.net/bleroy/archive/2005/04/28/405013.aspx

التي توفر شرح الأسباب أو بدلا من ذلك:

http://forums.asp.net/p/1191839/2052438.aspx#2052438

التي تنص التعليمة البرمجية الموجودة في المثال مماثلة ليدكم.

لقد حللت شيء مزيف من خلال خلق 2 خصائص:

public List<int> ModuleIDs { get .... set ... }
public string ModuleIDstring { get ... set ... }

على ModuleIDstring تحويل قيمته إلى قائمة مجموعات ModuleIDs الملكية.

وهذا أيضا جعل ModuleIDs قابلة للاستخدام من PropertyGrid.... الخ

حسنا, لم يكن أفضل ، typesafe الحل, ولكن بالنسبة لي كان يعمل.

تمرير قائمة من التعليمات البرمجية خلف...

aspx:

<UC:MyControl id="uc" runat="server" />

التعليمات البرمجية-خلف:

List<int> list = new List<int>();
list.add(1);
list.add(2);
list.add(3);

uc.ModuleIds = list;

الطريقة التي كنت تفعل في العادة هذا هو جعل الملكية التفاف ViewState جمع.طريقك تبدو أفضل إذا كان يمكن أن يتم العمل ، ولكن هذا سوف تحصل على هذه المهمة:

public IList<int> ModuleIds
{
   get
   {
       string moduleIds = Convert.ToString(ViewState["ModuleIds"])

       IList<int> list = new Collection<int>();

       foreach(string moduleId in moduleIds.split(","))
       {
          list.Add(Convert.ToInt32(moduleId));
       }

      return list;
   }
}

أعتقد أن المشكلة هي مجموعة{}.نوع محول ترغب في تغيير List<int> مرة أخرى في سلسلة ، ولكن CanConvertFrom() فشل List<int>.

يمكنك تمرير ذلك إلى سلسلة وتقسيم على فاصلة لملء الخاص متغير.لا تملك دقة الإسناد ، ولكن سوف تعمل.

private List<int> modules;
public string ModuleIds
{
  set{
    if (!string.IsNullOrEmpty(value))
    {
    if (modules == null) modules = new List<int>();
    var ids = value.Split(new []{','});
    if (ids.Length>0)
      foreach (var id in ids)
        modules.Add((int.Parse(id)));
    }
}

أعتقد أنك أفضل خيار هو أن تجعل النظام الخاص بك usercontrol لديك مصدر بيانات-نمط الملكية.

تأخذ المنشأة ككائن ومن ثم القيام ببعض نوع فحص ضد IList/ IEnumerable/ الخ للتأكد من أنه هو الصحيح.

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