2008-09-22 12 views
23

Tengo una matriz int como propiedad de un control de usuario web. Me gustaría establecer que la propiedad en línea si es posible utilizando la siguiente sintaxis:Pasar matriz int como parámetro en control de usuario web

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

Esto se producirá un error en tiempo de ejecución, ya que se espera un arreglo int real, sino una cadena se está pasando en su lugar. Puedo hacer myintarray una cadena y analizarla en el setter, pero me preguntaba si había una solución más elegante.

+1

Pregunta interesante ... – juan

Respuesta

20

Implementar un convertidor de tipos, aquí es uno, la advertencia: rápida & sucia, no para su uso en producción, 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(); 
    } 
} 

y la etiqueta de la propiedad de su control:

private int[] ints; 
[TypeConverter(typeof(IntsConverter))] 
public int[] Ints 
{ 
    get { return this.ints; } 
    set { this.ints = value; } 
} 
+0

Agregué un ejemplo a continuación que se compilará. ¡Gracias! – ern

+0

Esto no es suficiente. Ver http://weblogs.asp.net/bleroy/405013 –

5

me parece que el enfoque lógico — — y más extensible es tomar una página de los controles asp: lista:

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

Gracias. Esto puede funcionar, pero hay un montón de código adicional por adelantado. Estoy tratando de mantenerme lo más minimalista posible. – ern

0

hacen lo que Bill estaba hablando con la lista sólo tiene que crea una propiedad de lista en tu usuario c ontrol. Entonces puedes implementarlo como Bill describió.

0

Se podría añadir a los eventos de página dentro de la aspx algo como esto:

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

Para agregar elementos secundarios que hacen que su lista es necesario tener la configuración de control de una manera determinada:

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

Las acciones anteriores son el nombre de la propiedad en la que estarán los elementos secundarios. Utilizo una ArrayList, ya que no he probado nada con ella .:

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

cuando se inicializa su contorl, tendrá los valores de los elementos secundarios. Aquellos que puedan hacer una mini clase que solo contenga ints.

0

Puede implementar una clase de convertidor de tipo que convierta entre matriz int y tipos de datos de cadena. A continuación, decore su propiedad int array con TypeConverterAttribute, especificando la clase que implementó. Visual Studio luego usará su convertidor de tipo para conversiones de tipo en su propiedad.

6

@mathieu, muchas gracias por su código.He modificado un poco con el fin de compilar:

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

He reparado la respuesta original, puedes eliminar esta si quieres – juan

+1

(Lo arreglé con tu código de curso) – juan

2

También podría hacer algo como esto:

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

que se traducirá en:

<xx:CustomUserControl runat="server"> 
    <Values> 
      <xx:ArrayItem Value="1" /> 
    </Values> 
</xx:CustomUserControl> 
+1

Esto no funciona para mí – SashaArz

2

Gran @mathieu fragmento. Necesitaba usar esto para convertir longs, pero en lugar de hacer un LongArrayConverter, escribí una versión que usa 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(); 
    } 
} 

Esta versión debería funcionar con cualquier tipo que sea convertible de cadena.

[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; } 
Cuestiones relacionadas