今天做一个Web控件,其中一个属性是让用户选择页面上的一个DropDownList的ID,为了更好的用户设计体验,我想把控件所在页面的所有的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; }
}