为什么复合控件点击事件无法触发?

时间:2019-01-23 15:22:35

标签: c# asp.net custom-controls

我写了一个名为(WebDbConnection)的复合asp.net控件来管理数据库的连接字符串。 我添加了一个按钮“ btnConnect”,并在“ CreateChildControls”方法中为其创建了单击事件。

   public WebDbConnection(string extraParameters, string configConnectionName, string databaseName,
        bool showDbName, string dialogName, bool isEncrypted,ref Page page)
    {
        _currentPage = page;
        _extraParameters = extraParameters;
        _dialogName = dialogName;
        IsEncrypted = isEncrypted;
        _showDbName = showDbName;

        _configConnectionName = configConnectionName;
        LoadDefaultConnectionString(IsEncrypted);

        _databaseName = databaseName;


    }
protected void BtnConnect_Click(object sender, EventArgs e)
    {
        try
        {
            EnsureChildControls();
            _server = Dbconnection_txtServer.Text;
            _userName = Dbconnection_txtUser.Text;
            _password = Dbconnection_txtPass.Text;
            _databaseName = Dbconnection_txtdbname.Text;

            if (Connection.State == ConnectionState.Connecting)
                return;

            Connect();
            if (Connection.State == ConnectionState.Open)
                this.Controls.Clear();
            else
            {
                ScriptManager.RegisterStartupScript(this, this.GetType(), "alertbox",
                    "alert('Can not connect to server.')", true);

                Dbconnection_txtServer.Text = _server;
                Dbconnection_txtUser.Text = _userName;
                Dbconnection_txtPass.Text = _password;
                Dbconnection_txtdbname.Text = _databaseName;
            }

        }

        catch (Exception ex)
        {
            LastError = ex.Message;
            LoadDefaultConnectionString(IsEncrypted);
            Dbconnection_txtServer.Text = _server;
            Dbconnection_txtPass.Text = _password;
            Dbconnection_txtUser.Text = _userName;
        }
    }    
    protected override void CreateChildControls()
    {
        Controls.Clear();

        lbl_HeaderName = new Label();
        lbl_HeaderName.ID = "lbl_HeaderName";
        lbl_HeaderName.Text = "Server Credential";

        lbl_servername = new Label();
        lbl_servername.ID = "lbl_servername";
        lbl_servername.Text = "Server Name";

        Dbconnection_txtServer = new TextBox();
        Dbconnection_txtServer.ID = "Dbconnection_txtServer";

        lbl_username = new Label();
        lbl_username.ID = "lbl_username";
        lbl_username.Text = "User Name:";

        Dbconnection_txtUser = new TextBox();
        Dbconnection_txtUser.ID = "Dbconnection_txtUser";

        lbl_password = new Label();
        lbl_password.ID = "lbl_password";
        lbl_password.Text = "Password:";

        Dbconnection_txtPass = new TextBox();
        Dbconnection_txtPass.ID = "Dbconnection_txtPass";

        lbl_databasename = new Label();
        lbl_databasename.ID = "lbl_databasename";
        lbl_databasename.Text = "Database Name:";

        Dbconnection_txtdbname = new TextBox();
        Dbconnection_txtdbname.ID = "Dbconnection_txtdbname";

        btnConnect = new Button();
        btnConnect.ID = "btnConnect";
        btnConnect.Text = "Connect";
        btnConnect.Click += BtnConnect_Click;

        btnCancel = new Button();
        btnCancel.ID = "btnCancel";
        btnCancel.Text = "Cancel";
        btnCancel.Click += BtnCancel_Click;


        //add controls
        Controls.Add(lbl_password);
        Controls.Add(lbl_databasename);
        Controls.Add(lbl_servername);
        Controls.Add(lbl_username);
        Controls.Add(lbl_HeaderName);
        Controls.Add(Dbconnection_txtdbname);
        Controls.Add(Dbconnection_txtPass);
        Controls.Add(Dbconnection_txtServer);
        Controls.Add(Dbconnection_txtUser);
        Controls.Add(btnConnect);
        Controls.Add(btnCancel);
    } 
void ShowPage()
    {
        EnsureChildControls();
        if (!_currentPage.Form.Controls.Contains(this))
            _currentPage.Form.Controls.Add(this);
        else
        {
            _currentPage.Form.Controls.Remove(this);
            _currentPage.Form.Controls.Add(this);
        }

        Dbconnection_txtdbname.Text = _databaseName;
        if (!_showDbName)
        {
            lbl_databasename.Visible = false;
            Dbconnection_txtdbname.Visible = false;
        }

        //----------------------
        if (_dialogName.IsEmptyOrNull()) return;
        lbl_HeaderName.Text = "Fill " + _dialogName + " Information";
    }

这个想法是当我在内部调用“ ShowPage”方法时显示复合控件。 问题是,当我在其他页面上创建复合控件时,“ ShowPage”可以正常工作,但是在回发时“ BtnConnect”单击事件未触发,仅发生了回发表单!

几个小时之内,我发现当我在page_load事件中将WebDbConnection类的实例添加到窗体控件中时,我的控件可以正常工作。

protected void Page_Load(object sender, EventArgs e)
{
    Page.Form.Controls.Add(WebDbConnection_instance);
}

但是如何将控件添加到我的控件中而不是在客户的page_load事件上?

1 个答案:

答案 0 :(得分:0)

经过十天的谷歌搜索和一些方法测试之后,我找到了一种解决方案,可以拦截发送给用户的类对象和HTML标签后面的代码。 因此,我没有使用复合控件,而是使用HTTPModule“ myModule1”来捕获Ajax请求,然后创建所需的HTML标记并将其发送给用户。 有关详情,请参见此帖子:How to search and replace the requestContext.Response in a IHttpModule?

噩梦还没有结束!!! 经过上述方法后,您应该在web.config文件(<system.webserver>标签)中注册HTTPModule,因此我想随时随地动态注册“ myModule1”。为此,我在“ myModule1”类的顶部使用以下指令。

[assembly: PreApplicationStartMethod(typeof(DreamyTools.DataBase.Web.MyModule1), "Initialize")]
 namespace DataBase.Web
  {
   public class MyModule1 : IHttpModule
   {
     public static void Initialize()
      {
           Microsoft.Web.Infrastructure.DynamicModuleHelper
           .DynamicModuleUtility.RegisterModule(MyModule1);
       }

因此,只要引用此对象,就会调用“ Initialize”方法并向web.config注册。

我希望这种方法对开发人员创建Ajax调用和在自己的SDK中获取请求很有帮助。