2008-09-22 35 views
23

我有一個int數組作爲Web用戶控件的屬性。我想如果可能的話使用下面的語法來設置該屬性,內聯:在Web用戶控件中傳遞int數組作爲參數

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

這將在運行時失敗,因爲它會在期待實際int數組,而是一個字符串被改爲通過。我可以讓myintarray成爲一個字符串並在setter中解析它,但我想知道是否有更優雅的解決方案。

+1

有趣的問題... – juan 2008-09-22 19:18:56

回答

20

實現一個類型轉換器,這裏是一個警告:快速&骯髒的,而不是用於生產,等:

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

我在下面添加了一個例子來編譯。謝謝! – ern 2008-09-22 20:47:21

+0

這還不夠。見http://weblogs.asp.net/bleroy/405013 – 2016-04-20 14:47:14

5

在我看來,邏輯—和更具擴展性—方法是從asp:列表控件採取頁:

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

謝謝。這可能會起作用,但預先提供了很多額外的代碼。我試圖保持儘可能簡約。 – ern 2008-09-22 19:37:15

0

不要做什麼比爾與您只需要在列表說起在你的用戶c上創建一個List屬性ONTROL。然後你可以像Bill所描述的那樣執行它。

0

你可以添加到頁面的事件ASPX這樣的事情裏面:

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

當您的控制器初始化時,它將具有子元素的值。那些你可以製作一個迷你課程,只是持有整數。

0

你可以實現一個在int數組和字符串數據類型之間轉換的類型轉換器類。 然後用TypeConverterAttribute裝飾你的int數組屬性,指定你實現的類。然後,Visual Studio將使用您的類型轉換器對您的屬性進行類型轉換。

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

我修復了原來的答案,如果你想要 – juan 2008-09-22 20:51:24

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> 
2

大段@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; }