2008-09-22 26 views
23

Tôi có một mảng int làm thuộc tính của Điều khiển người dùng web. Tôi muốn đặt thuộc tính đó nội dòng nếu có thể bằng cách sử dụng cú pháp sau:Truyền mảng int làm tham số trong điều khiển người dùng web

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

Điều này sẽ không chạy được vì nó sẽ mong đợi một mảng int thực tế, nhưng một chuỗi đang được chuyển. Tôi có thể làm cho myintarray một chuỗi và phân tích nó trong setter, nhưng tôi đã tự hỏi nếu có một giải pháp thanh lịch hơn.

+1

Câu hỏi thú vị ... – juan

Trả lời

20

Thực hiện một chuyển đổi loại hình, đây là một, cảnh báo: nhanh chóng & bẩn, không để sử dụng sản xuất, vv:

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

và thẻ tài sản của kiểm soát của bạn:

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

Tôi đã thêm một ví dụ bên dưới sẽ biên dịch. Cảm ơn! – ern

+0

Điều này là không đủ. Xem http://weblogs.asp.net/bleroy/405013 –

5

Dường như với tôi rằng — cách tiếp cận logic — và mở rộng hơn nữa là để có một trang từ các điều khiển danh sách asp::

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

Cảm ơn. Điều này có thể làm việc, nhưng có rất nhiều mã thêm lên phía trước. Tôi đang cố gắng ở mức tối giản nhất có thể. – ern

0

Đừng làm những gì Bill đang nói về với danh sách bạn chỉ cần tạo thuộc tính Danh sách trên người dùng của bạn c ontrol. Sau đó, bạn có thể thực hiện nó như Bill mô tả.

0

Bạn có thể thêm vào các sự kiện trang bên trong một cái gì đó aspx như thế này:

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

Để thêm phần tử con mà làm cho danh sách của bạn, bạn cần phải có thiết lập kiểm soát của bạn một cách chắc chắn:

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

Các hành động ở trên là tên của cproperty các yếu tố con sẽ được in Tôi sử dụng một ArrayList, như tôi đã không kiểm tra bất cứ điều gì khác với nó .:

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

khi contorl của bạn được khởi tạo, nó sẽ có các giá trị của các phần tử con. Những người bạn có thể làm cho một lớp học nhỏ mà chỉ giữ ints.

0

Bạn có thể thực hiện một lớp chuyển đổi kiểu chuyển đổi giữa các kiểu dữ liệu mảng và chuỗi int. Sau đó, trang trí thuộc tính mảng int của bạn với TypeConverterAttribute, chỉ rõ lớp mà bạn đã triển khai. Visual Studio sau đó sẽ sử dụng trình chuyển đổi loại của bạn để nhập các chuyển đổi trên thuộc tính của bạn.

6

@mathieu, cảm ơn bạn rất nhiều vì mã của bạn.Tôi sửa đổi nó một chút để biên dịch:

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

Tôi đã sửa câu trả lời gốc, bạn có thể xóa câu trả lời này nếu bạn muốn – juan

+1

(Tôi đã sửa mã đó với mã của bạn) – juan

2

Bạn cũng có thể làm một cái gì đó như thế này:

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

mà sẽ cho kết quả:

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

Điều này không hiệu quả đối với tôi – SashaArz

2

lớn đoạn @mathieu. Tôi cần sử dụng điều này để chuyển đổi thời gian dài, nhưng thay vì tạo LongArrayConverter, tôi đã viết một phiên bản sử dụng 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(); 
    } 
} 

Phiên bản này sẽ hoạt động với bất kỳ loại nào có thể chuyển đổi từ chuỗi.

[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; } 
Các vấn đề liên quan