我有一个 UserControl,一个
asp:DropDownList
的包装器。这是一个将重复多次的控件,我希望避免在其编写的每个位置的代码隐藏中编写事件挂钩。
我一直在尝试各种方法来在控件声明中声明事件,但是无论我做什么,它似乎最终都是空的。
这是我的 Dropdown.ascx 文件的示例:
public partial class Dropdown : UserControl {
public delegate void SelectedIndexChangedHandler(object sender, EventArgs e);
public event SelectedIndexChangedHandler SelectedIndexChanged;
protected void Page_Load(object sender, EventArgs e) {
DataBind(); //including page_load calling databind in case that is somehow related
}
protected void dropDown_SelectedIndexChanged(object sender, EventArgs e) {
if (SelectedIndexChanged != null) {
SelectedIndexChanged(sender, e);
}
}
}
其中
dropDown
是控件中的 asp:DropDownList
。
这是我在 aspx 主页面中的声明:
<CustomControl:Dropdown
runat="server"
ID="DropdownOne"
SelectedIndexChanged="DropdownOne_SelectedIndexChanged"
>
...
</CustomControl:Dropdown>
其中页面方法是
protected void DropdownOne_SelectedIndexChanged(object sender, EventArgs e)
在生命周期的所有点上,
SelectedIndexChanged
都是null
。
如果我将
DropdownOne.SelectedIndexChanged += DropdownOne_SelectedIndexChanged;
添加到 Page_Load(或生命周期的其他部分),一切都会正常工作。不幸的是,这不是我们想要的,据我所知,我想要完成的任务是可行的。
好的,那么说一下这个用户控件:
标记:
<asp:DropDownList ID="MyDrop" runat="server"
OnSelectedIndexChanged="MyDrop_SelectedIndexChanged"
AutoPostBack="true" >
</asp:DropDownList>
背后的用户代码:
公共分部类 MyDropDown :System.Web.UI.UserControl
{
public string MySelectRow = "";
private string m_SQL = "";
public delegate void MySelectedIndexHandler(object sender, EventArgs e);
public event MySelectedIndexHandler SelectedIndexChanged;
protected void MyDrop_SelectedIndexChanged(object sender, EventArgs e)
{
SelectedIndexChanged(sender, e);
}
public string DataValueField
{
get
{ return MyDrop.DataValueField; }
set
{MyDrop.DataValueField = value;}
}
public string DataTextField
{
get
{ return MyDrop.DataTextField; }
set
{ MyDrop.DataTextField = value; }
}
public DropDownList ThedropDownList
{
get { return this.MyDrop; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
}
}
void LoadData()
{
MyDrop.DataSource = General.MyRst(SQL);
MyDrop.DataValueField = DataValueField;
MyDrop.DataTextField = DataTextField;
MyDrop.DataBind();
MyDrop.Items.Insert(0, new ListItem(MySelectRow, ""));
}
public ListItem SelectedItem
{
get { return MyDrop.SelectedItem; }
}
public int SelectedIndex
{
get { return MyDrop.SelectedIndex; }
}
public string SQL {
get { return m_SQL; }
set
{
m_SQL = value;
LoadData();
}
}
}
这里最重要的可能是如何获取所选项目。你必须将其作为公共财产公开。
例如,上面这个:
public ListItem SelectedItem
{
get { return MyDrop.SelectedItem; }
}
public int SelectedIndex
{
get { return MyDrop.SelectedIndex; }
}
如果您错过了上述内容,则所选索引将不起作用。 (所选项目也是如此) 现在,在 aspx 页面上,我们有这个标记:
<uc1:MyDropDown runat="server" ID="MyDropDown"
OnSelectedIndexChanged="MyDropDown_SelectedIndexChanged"
/>
<%-- In this example we set Data Value and Data Text
-- above example, we used code behind on page load to set Value & Text fields
-- <uc1:MyDropDown runat="server" ID="MyDropDown"
DataValueField="ID"
DataTextField="HotelName"
OnSelectedIndexChanged="MyDropDown_SelectedIndexChanged"
/>--%>
以及 aspx 页面的代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// do NOT forget to wrap this code in !IsPostBack
// (a dropdown list will not work, if we don't check
// for !IsPostback - same goes for UC
MyDropDown.DataValueField = "ID";
MyDropDown.DataTextField = "HotelName";
MyDropDown.MySelectRow = "Please Select Hotel";
MyDropDown.SQL = @"SELECT ID, HotelName FROM tblHotelsA
ORDER BY HotelName";
}
}
protected void MyDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
Debug.Print($"Selected Text = {MyDropDown.SelectedItem.Text}");
Debug.Print($"Selected Value = {MyDropDown.SelectedItem.Value}");
Debug.Print($"Selected Value = {MyDropDown.SelectedIndex}");
}
不清楚您是否希望为 aspx 页面连接事件?
但是,intel-sense 应该适合您,但请注意:
因此,我在上面使用了创建新事件的方法,就像我们为所有控件(甚至非用户控件)所做的那样。
但是,翻到后面的代码,您会注意到发送者和参数丢失,如上所示。
因此,您必须手动编辑/添加参数,如下所示:
protected void MyDropDown1_SelectedIndexChanged(object sender, EventArgs e)
{
}
我不知道如何“修复”这个错误,或者让 VS 添加“对象发送者”和“EventArgs e”,但是在让 VS 创建事件存根后面的代码后添加这个是一个简单的事情你在aspx页面中。
标准控件将使用 intel-sense 为您创建事件存根,而用户控件则创建代码存根,但需要您手动将参数添加到代码存根。