如何在 ASPX 页面中正确连接 UserControl EventHandler(不是代码隐藏)

问题描述 投票:0回答:1

我有一个 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(或生命周期的其他部分),一切都会正常工作。不幸的是,这不是我们想要的,据我所知,我想要完成的任务是可行的。

c# asp.net webforms event-handling aspx-user-control
1个回答
0
投票

好的,那么说一下这个用户控件:

标记:

<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 为您创建事件存根,而用户控件则创建代码存根,但需要您手动将参数添加到代码存根。

© www.soinside.com 2019 - 2024. All rights reserved.