asp.net控件开发基础(10)

本文介绍如何创建自定义控件并实现集合属性效果,包括定义集合属性、使用自定义编辑器及类型转换器来简化操作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  上一篇讨论了类型转换器的使用,这次继续讨论讨论集合属性的使用

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

None.gif < asp:DropDownList  ID ="DropDownList1"  runat ="server" >
None.gif            
< asp:ListItem > 测试1 </ asp:ListItem >
None.gif            
< asp:ListItem > 测试2 </ asp:ListItem >
None.gif            
< asp:ListItem > 测试3 </ asp:ListItem >
None.gif        
</ asp:DropDownList >


1.实现集合属性效果

经过前面几篇的学习,相信这一篇看起来已经相对简单了.我们要做的就是,先定义一个复杂属性,然后用迭代语句获取数组数据即可.

如果看过前面几篇就看看下面代码吧,相信看起来很简单,我们模仿一个DropDownList,为其属性添加背景属性,代码如下

先定义一个集合属性,如下

None.gif   public   class  DropItem
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
private string text;
InBlock.gif        
private string value;
InBlock.gif        
private Color backColor;
InBlock.gif
InBlock.gif        [
InBlock.gif         Category(
"Behavior"),
InBlock.gif         DefaultValue(
""),
InBlock.gif         Description(
"项文本"),
InBlock.gif         NotifyParentProperty(
true),
InBlock.gif         ]
InBlock.gif        
public String Text
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return text;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                text 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [
InBlock.gif        Category(
"Behavior"),
InBlock.gif        DefaultValue(
""),
InBlock.gif        Description(
"项值"),
InBlock.gif        NotifyParentProperty(
true),
InBlock.gif        ]
InBlock.gif        
public String Value
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return value;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.value = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [
InBlock.gif        Category(
"Behavior"),
InBlock.gif        DefaultValue(
""),
InBlock.gif        Description(
"背景颜色"),
InBlock.gif        NotifyParentProperty(
true),
InBlock.gif        ]
InBlock.gif        
public Color BackColor
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
return backColor;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                backColor 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedBlockEnd.gif    }


 然后自定义一个控件,输出集合属性,如下代码

None.gif  [ParseChildren( true " DropItemList " )]
None.gif   
public   class  DropColor:WebControl
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif       
private ArrayList dropItemList;
InBlock.gif
InBlock.gif        [
InBlock.gif        Category(
"Behavior"),
InBlock.gif        Description(
"项集合"),
InBlock.gif        DesignerSerializationVisibility(
InBlock.gif            DesignerSerializationVisibility.Content),
InBlock.gif        PersistenceMode(PersistenceMode.InnerDefaultProperty),
InBlock.gif       
InBlock.gif        ]
InBlock.gif
InBlock.gif       
//定义集合属性
InBlock.gif
       public ArrayList DropItemList
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (dropItemList == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    dropItemList 
= new ArrayList();
ExpandedSubBlockEnd.gif                }

InBlock.gif                
return dropItemList;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif       
//重写标签
InBlock.gif
       protected override HtmlTextWriterTag TagKey
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif           
get
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif               
return HtmlTextWriterTag.Select;
ExpandedSubBlockEnd.gif           }

ExpandedSubBlockEnd.gif       }

InBlock.gif       
protected override void RenderContents(HtmlTextWriter writer)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif           
//输出集合属性
InBlock.gif
           foreach (DropItem item in dropItemList)
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif               DropItem dr 
= item as DropItem;
InBlock.gif               
if (dropItemList != null && dropItemList.Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif               
dot.gif{
InBlock.gif               
//颜色转换
InBlock.gif
               WebColorConverter wcc = new WebColorConverter();
InBlock.gif               writer.AddAttribute(HtmlTextWriterAttribute.Value, dr.Value.ToString());
InBlock.gif               writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, wcc.ConvertToString(dr.BackColor));
InBlock.gif               writer.RenderBeginTag(HtmlTextWriterTag.Option);
InBlock.gif               writer.Write(dr.Text.ToString());
InBlock.gif               writer.RenderEndTag();
ExpandedSubBlockEnd.gif               }

ExpandedSubBlockEnd.gif           }

InBlock.gif           
base.RenderContents(writer);
ExpandedSubBlockEnd.gif       }

ExpandedBlockEnd.gif    }


上面代码注意颜色类型之间的转换,以下为HTML代码

None.gif < custom:DropColor  ID ="DropColor1"  runat ="server"  ForeColor ="White" >
None.gif        
< custom:DropItem  BackColor ="Yellow"  Text ="黄色"  Value ="yellow"   />
None.gif        
< custom:DropItem  BackColor ="Red"  Text ="红色"  Value ="red"   />
None.gif        
< custom:DropItem  BackColor ="Blue"  Text ="蓝色"  Value ="blue"   />
None.gif        
< custom:DropItem  BackColor ="Green"  Text ="绿色"  Value ="green"   />
None.gif        
< custom:DropItem  BackColor ="Black"  Text ="黑色"  Value ="Black"   />
None.gif        
</ custom:DropColor >


输出以后的效果如下图




效果还不错吧,而且挺实用的.

2.定义编辑器

大家一般在添加集合属性的时候往往会在.net自带的编辑器中添加数据,这样可以提高效果,不用在HTML视图添加数据.如下图




我们也可以为其添加自定义的编辑器,其实我们一直在用.net自带的编辑器,我们称之为 UI编辑器或视图编辑器,如颜色,时间,超级链接等,大家该有所体会

其编辑器的基类为位于 System.Drawing.Design命名空间的 UITypeEditor,很多UI编辑器都从此类派生,有兴趣的可以去了解下这个类.

你们如何使用使用UI编辑器呢?也跟上一篇讲的类型转换器一样,你先要定义一个UI编辑器,然后与相关属性关联起来.

因为所定义的是一个集合类,而.net已经为我们提供了一个集合编辑器的 CollectionEditor类,其已经为我们做了很多工作了,我们最简单的只需重写几个方法即可.具体其他属性和方法请参考MSDN,如下代码

None.gif      public   class  DropItemEditor : CollectionEditor
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
public DropItemEditor(Type type)
InBlock.gif            : 
base(type)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif        
//一次可否选择多项
InBlock.gif
        protected override bool CanSelectMultipleInstances()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return false;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//获取此集合包含的数据类型
InBlock.gif
        protected override Type CreateCollectionItemType()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return typeof(DropItem);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


然后把集合属性与编辑器关联起来,添加了一个 EditorAttribute,第一个参数为指定的编辑器类型,第二个为基本类型

None.gif         [
None.gif        Category(
" Behavior " ),
None.gif        Description(
" 项集合 " ),
None.gif        DesignerSerializationVisibility(
None.gif            DesignerSerializationVisibility.Content),
None.gif        PersistenceMode(PersistenceMode.InnerDefaultProperty),
None.gif        Editor(
typeof(DropItemEditor), typeof (UITypeEditor)),
None.gif        ]
None.gif       
// 定义集合属性
None.gif
        public  ArrayList DropItemList
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (dropItemList == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    dropItemList 
= new ArrayList();
ExpandedSubBlockEnd.gif                }

InBlock.gif                
return dropItemList;
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif


然后再来看下效果,这样就方面很多了.



如果还不想看到编辑器里的CustomComponents的命名空间的话,你可以像上一篇一样自定义一个类型转换器,代码如下:

ContractedBlock.gif ExpandedBlockStart.gif
None.gif    public class DropItemConverter : ExpandableObjectConverter
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
方法#region 方法
InBlock.gif        
InBlock.gif        
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (sourceType == typeof(string))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return base.CanConvertFrom(context, sourceType);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (destinationType == typeof(string))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return base.CanConvertTo(context, destinationType);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture,
InBlock.gif            
object value)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (value == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return new DropItem();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
if (value is string)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
string s = (string)value;
InBlock.gif                
if (s.Length == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
return new DropItem();
ExpandedSubBlockEnd.gif                }

InBlock.gif                
return "DropItem";
InBlock.gif
ExpandedSubBlockEnd.gif            }

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

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

ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
if (destinationType == typeof(string))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (value == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
return String.Empty;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
return "DropItem";
ExpandedSubBlockEnd.gif            }

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

ExpandedSubBlockEnd.gif        
#endregion

ExpandedBlockEnd.gif    }


然后还是照着步骤把属性与其关联起来

None.gif   [TypeConverter( typeof (DropItemConverter))]
None.gif    
public   class  DropItem
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
ExpandedBlockEnd.gif    }


再来看下效果




好了,这回讲的比较简单又实用,希望对大家有帮助.大家同时也可以参考MSDN里的例子,下面的示例代码下载我也加上了MSDN的例子.
已经写了10篇了,我们应该有些基础了,我想大家该可以做出一些简单实用的控件了.

示例代码下载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值