我想把控件所在页面的所有的dropdownlist控件都遍历出来,然后用户直接选择就可以了。这需要写一个设计器用的类,派生自uitypeeditor
using system;
using system.drawing.design;
using system.web.ui;
using system.windows.forms;
using system.windows.forms.design;
namespace mvcapp.webforms.controls
{
public class iteratepagecontrolsuitypeeditor : uitypeeditor
{
public override uitypeeditoreditstyle geteditstyle(system.componentmodel.itypedescriptorcontext context)
{
return uitypeeditoreditstyle.dropdown;
}
public override object editvalue(system.componentmodel.itypedescriptorcontext context, iserviceprovider provider, object value)
{
iwindowsformseditorservice service = provider.getservice(typeof(iwindowsformseditorservice)) as iwindowsformseditorservice;
listbox lbvalues = new listbox();
lbvalues.borderstyle = borderstyle.none;
iteratepagedropdownlist(lbvalues, context, value);
lbvalues.click += (sender, arg) =>
{
service.closedropdown();
};
service.dropdowncontrol(lbvalues);
if (lbvalues.selecteditem != null)
return lbvalues.selecteditem.tostring();
else
return "";
}
private void iteratepagedropdownlist(listbox lbvalues, system.componentmodel.itypedescriptorcontext context, object value)
{
system.web.ui.webcontrols.webcontrol self = context.instance as system.web.ui.webcontrols.webcontrol;
page page=null;
if (self.site.container.components.count > 0)
page = self.site.container.components[0] as page;
int currentindex = -1;
foreach (system.web.ui.control item in page.controls)
{
if (item is system.web.ui.webcontrols.dropdownlist == false || self.id == item.id)
continue;
currentindex = lbvalues.items.add(item.id);
if (item.id == value.tostring())
lbvalues.selectedindex = currentindex;
}
}
}
}
使用方法
[editor(typeof(iteratepagecontrolsuitypeeditor), typeof(system.drawing.design.uitypeeditor))]
public string clientdropdownlistid
{
get { return m_clientdropdownlistid; }
set { m_clientdropdownlistid = value; }
}
看一个自定控件实现代码
要实现这样的效果,我们只需要做2件事情。
1. 在控件类库中,添加一个windowform类,然后编辑相应的界面,并初始化
因为默认情况下 控件在designer.cs中定义为private,所以我们将他改为public。
public partial class categorywindow : form
{
public categorywindow()
{
initializecomponent();
setselectdata();
}
public void setselectdata()
{
try
{
this.combobox1.items.add("水果");
this.combobox1.items.add("蔬菜");
this.combobox1.items.add("肉类");
this.combobox1.items.add("蛋类");
this.combobox1.items.add("面食");
this.combobox1.selecteditem = combobox1.items[0];
}
catch (exception eee)
{
throw eee;
}
finally
{
}
}
}
2. 定制自己的uitypeeditor类。
public class categorymodaleditor : system.drawing.design.uitypeeditor
{
public categorymodaleditor()
{
}
public override system.drawing.design.uitypeeditoreditstyle geteditstyle(system.componentmodel.itypedescriptorcontext context)
{
return uitypeeditoreditstyle.modal;
}
public override object editvalue(system.componentmodel.itypedescriptorcontext context,
system.iserviceprovider provider, object value)
{
iwindowsformseditorservice service =
(iwindowsformseditorservice)provider.getservice(typeof(iwindowsformseditorservice));
if (service == null)
{
return null;
}
categorywindow form = new categorywindow();
if (service.showdialog(form) == dialogresult.ok)
{
return form.combobox1.selecteditem;
}
return value;
}
}
2. 属性下拉编辑器.
1.在classlibrary中,新建一个usercontrol(categorydorpdown.cs).
2.实现自定义uitypeeditor.
3.因为windowform里的控件在designer.cs声明为private,如果声明为public,则在自定义uitypeeditor中引用不到控件,所以我们需要
combobox obj = dropform.controls[2] as combobox;需要找到下拉控件 并根据value 参数赋值,但我们要判断是否控件为null和是否为"".
赋值为obj.text=value as string.
public class categorydropdowneditor : system.drawing.design.uitypeeditor
{
public categorydropdowneditor()
{
}
public override system.drawing.design.uitypeeditoreditstyle
geteditstyle(system.componentmodel.itypedescriptorcontext context)
{
//指定编辑样式为下拉形状, 且基于control 类型
return uitypeeditoreditstyle.dropdown;
}
public override object editvalue(system.componentmodel.itypedescriptorcontext context,
system.iserviceprovider provider, object value)
{
//取得编辑器服务对象
iwindowsformseditorservice service =
(iwindowsformseditorservice)provider.getservice(typeof(iwindowsformseditorservice));
if (service == null)
{
return null;
}
//定义一个用户控件对象
string original = string.empty;
string strreturn = string.empty;
categorydorpdown dropform = new categorydorpdown(service);
combobox obj = dropform.controls[2] as combobox;
if (obj != null)
{
if (value != null&&value.tostring()!="")
{
obj.text= (string)value;
}
}
service.dropdowncontrol(dropform);
strreturn = dropform.strreturnvalue;
if (strreturn + string.empty != string.empty)
{
return strreturn;
}
return (string)value;
}
}
3.
在这个自定义属性中,我继承stringconverter并通过返回一个string数组来实现下拉:
代码
public class customcollectionpropertyconverter : stringconverter
{
public override bool getstandardvaluessupported(itypedescriptorcontext
context)
{
return true;
}
public override bool getstandardvaluesexclusive(itypedescriptorcontext
context)
{
return false;
}
public override standardvaluescollection
getstandardvalues(itypedescriptorcontext context)
{
string[] strarray = new string[] { "水果", "蔬菜", "肉食", "面食", "蛋类" };
standardvaluescollection returnstandardvaluescollection = new
standardvaluescollection(strarray);
return returnstandardvaluescollection;
}
}
没有特别之处,只是当我们重写getstandardvaluesexclusive为true是,我们就不能手动输入字符串,只能根据下拉选择值.