asp.net控件開發基礎(10) --------再談屬性,實現自定義控件集合屬性

上一篇討論了類型轉換器的使用,這次繼續討論討論集合屬性的使用

集合屬性相信大家都很熟悉也很常用,如DropDownList,ListBox等控件

<asp:DropDownList ID="DropDownList1" runat="server">
            
<asp:ListItem>測試1</asp:ListItem>
            
<asp:ListItem>測試2</asp:ListItem>
            
<asp:ListItem>測試3</asp:ListItem>
        
</asp:DropDownList>


1.實現集合屬性效果

經過前面幾篇的學習,相信這一篇看起來已經相對簡單了.我們要做的就是,先定義一個複雜屬性,然後用迭代語句獲取數組數據即可.

如果看過前面幾篇就看看下面代碼吧,相信看起來很簡單,我們模仿一個DropDownList,爲其屬性添加背景屬性,代碼如下

先定義一個集合屬性,如下

 public class DropItem
    
{
        
private string text;
        
private string value;
        
private Color backColor;

        [
         Category(
"Behavior"),
         DefaultValue(
""),
         Description(
"項文本"),
         NotifyParentProperty(
true),
         ]
        
public String Text
        
{
            
get
            
{
                
return text;
            }

            
set
            
{
                text 
= value;
            }

        }


        [
        Category(
"Behavior"),
        DefaultValue(
""),
        Description(
"項值"),
        NotifyParentProperty(
true),
        ]
        
public String Value
        
{
            
get
            
{
                
return value;
            }

            
set
            
{
                
this.value = value;
            }

        }


        [
        Category(
"Behavior"),
        DefaultValue(
""),
        Description(
"背景顏色"),
        NotifyParentProperty(
true),
        ]
        
public Color BackColor
        
{
            
get
            
{

                
return backColor;
            }

            
set
            
{
                backColor 
= value;
            }

        }


    }


 然後自定義一個控件,輸出集合屬性,如下代碼

 [ParseChildren(true"DropItemList")]
   
public class DropColor:WebControl
    
{
       
private ArrayList dropItemList;

        [
        Category(
"Behavior"),
        Description(
"項集合"),
        DesignerSerializationVisibility(
            DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerDefaultProperty),
       
        ]

       
//定義集合屬性
       public ArrayList DropItemList
        
{
            
get
            
{
                
if (dropItemList == null)
                
{
                    dropItemList 
= new ArrayList();
                }

                
return dropItemList;
            }

        }


       
//重寫標籤
       protected override HtmlTextWriterTag TagKey
       
{
           
get
           
{
               
return HtmlTextWriterTag.Select;
           }

       }

       
protected override void RenderContents(HtmlTextWriter writer)
       
{
           
//輸出集合屬性
           foreach (DropItem item in dropItemList)
           
{
               DropItem dr 
= item as DropItem;
               
if (dropItemList != null && dropItemList.Count > 0)
               
{
               
//顏色轉換
               WebColorConverter wcc = new WebColorConverter();
               writer.AddAttribute(HtmlTextWriterAttribute.Value, dr.Value.ToString());
               writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, wcc.ConvertToString(dr.BackColor));
               writer.RenderBeginTag(HtmlTextWriterTag.Option);
               writer.Write(dr.Text.ToString());
               writer.RenderEndTag();
               }

           }

           
base.RenderContents(writer);
       }

    }


上面代碼注意顏色類型之間的轉換,以下爲HTML代碼

<custom:DropColor ID="DropColor1" runat="server" ForeColor="White">
        
<custom:DropItem BackColor="Yellow" Text="黃色" Value="yellow" />
        
<custom:DropItem BackColor="Red" Text="紅色" Value="red" />
        
<custom:DropItem BackColor="Blue" Text="藍色" Value="blue" />
        
<custom:DropItem BackColor="Green" Text="綠色" Value="green" />
        
<custom:DropItem BackColor="Black" Text="黑色" Value="Black" />
        
</custom:DropColor>


輸出以後的效果如下圖




效果還不錯吧,而且挺實用的.

2.定義編輯器

大家一般在添加集合屬性的時候往往會在.net自帶的編輯器中添加數據,這樣可以提高效果,不用在HTML視圖添加數據.如下圖




我們也可以爲其添加自定義的編輯器,其實我們一直在用.net自帶的編輯器,我們稱之爲 UI編輯器或視圖編輯器,如顏色,時間,超級鏈接等,大家該有所體會

其編輯器的基類爲位於System.Drawing.Design命名空間的UITypeEditor,很多UI編輯器都從此類派生,有興趣的可以去了解下這個類.

你們如何使用使用UI編輯器呢?也跟上一篇講的類型轉換器一樣,你先要定義一個UI編輯器,然後與相關屬性關聯起來.

因爲所定義的是一個集合類,而.net已經爲我們提供了一個集合編輯器的CollectionEditor類,其已經爲我們做了很多工作了,我們最簡單的只需重寫幾個方法即可.具體其他屬性和方法請參考MSDN,如下代碼

    public class DropItemEditor : CollectionEditor
    
{
        
public DropItemEditor(Type type)
            : 
base(type)
        
{
        }

        
//一次可否選擇多項
        protected override bool CanSelectMultipleInstances()
        
{
            
return false;
        }


        
//獲取此集合包含的數據類型
        protected override Type CreateCollectionItemType()
        
{
            
return typeof(DropItem);
        }

    }


然後把集合屬性與編輯器關聯起來,添加了一個EditorAttribute,第一個參數爲指定的編輯器類型,第二個爲基本類型

        [
        Category(
"Behavior"),
        Description(
"項集合"),
        DesignerSerializationVisibility(
            DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerDefaultProperty),
        Editor(
typeof(DropItemEditor), typeof(UITypeEditor)),
        ]
       
//定義集合屬性
       public ArrayList DropItemList
        
{
            
get
            
{
                
if (dropItemList == null)
                
{
                    dropItemList 
= new ArrayList();
                }

                
return dropItemList;
            }

        }



然後再來看下效果,這樣就方面很多了.



如果還不想看到編輯器裏的CustomComponents的命名空間的話,你可以像上一篇一樣自定義一個類型轉換器,代碼如下:


    public class DropItemConverter : ExpandableObjectConverter
    
{
        
#region 方法
        
        
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        
{
            
if (sourceType == typeof(string))
            
{
                
return true;
            }

            
return base.CanConvertFrom(context, sourceType);
        }


        
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        
{
            
if (destinationType == typeof(string))
            
{
                
return true;
            }

            
return base.CanConvertTo(context, destinationType);
        }


        
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture,
            
object value)
        
{
            
if (value == null)
            
{
                
return new DropItem();
            }

            
if (value is string)
            
{
                
string s = (string)value;
                
if (s.Length == 0)
                
{
                    
return new DropItem();
                }

                
return "DropItem";

            }

            
return base.ConvertFrom(context, culture, value);
        }


        
public override object ConvertTo(
            ITypeDescriptorContext context,
            CultureInfo culture, 
object value, Type destinationType)
        
{
            
if (value != null)
            
{
                
if (!(value is DropItem))
                
{
                    
throw new ArgumentException(
                        
"Invalid DropItem""value");
                }

            }


            
if (destinationType == typeof(string))
            
{
                
if (value == null)
                
{
                    
return String.Empty;
                }

                
return "DropItem";
            }

            
return base.ConvertTo(context, culture, value,
                destinationType);
        }

        
#endregion

    }


然後還是照着步驟把屬性與其關聯起來

  [TypeConverter(typeof(DropItemConverter))]
    
public class DropItem
    
{
    }


再來看下效果


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章