1

I have a search function which looks up specific users in my OleDb database. For each user, a row in a table is created containing his name, boolean saying if he is an admin or not and a delete button. The delete button is not working as expected, it doesn't execute the method that is linked to it. My code is located in the Search_Click event which executes right after the admin clicks the search button to search for specific users. I tried to place a pre-defined button from my code but in Page_Load instead and it works as expected. How can I get the button to work from the Search_Click as well? Basically, after dynamically creating the LinkButtons according to the user search text and clicking the search button (Search_Click) I need to find a way to register the click event on page load event, I do not know how to do that because the linkbuttons HAVE to be created in the click event of the search button but they also have to be registered via page load.

using (OleDbDataReader reader = cmd.ExecuteReader())
{
    Table table = new Table();
    TableRow row = new TableRow();
    TableCell cell = new TableCell();
    Label label = new Label();
    while (reader.Read())
    {
        row = new TableRow();
        cell = new TableCell();
        label = new Label();

        label.Text = reader.GetString(0);
        cell.Controls.Add(label);
        cell.BorderStyle = BorderStyle.Solid;
        row.Cells.Add(cell);

        cell = new TableCell();
        label = new Label();

        label.Text = reader.GetBoolean(1).ToString();
        cell.Controls.Add(label);
        cell.BorderStyle = BorderStyle.Solid;
        row.Cells.Add(cell);

        cell = new TableCell();
        LinkButton button = new LinkButton();

        button.Text = "Delete";
        button.ID = (string) reader["uName"];
        button.CommandName = (string)reader["uName"];
        button.Click += new EventHandler(DeleteUser);

        cell.Controls.Add(button);
        cell.BorderStyle = BorderStyle.Solid;
        row.Cells.Add(cell);

        table.Rows.Add(row);
    }
    table.Style.Add(HtmlTextWriterStyle.MarginLeft, "auto");
    table.Style.Add(HtmlTextWriterStyle.MarginRight, "auto");
    TableHolder.Controls.Add(table);
}

DeleteUser:

 protected void DeleteUser(object sender, EventArgs e)
    {
        try
        {
            LinkButton button = (LinkButton)sender;
            string path = Server.MapPath(@"App_Data/ArcadeDatabase.accdb");
            using (OleDbConnection con = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + "; Persist Security Info = False;"))
            {
                try
                {
                    con.Open();
                }
                catch(Exception ex)
                {
                    helper.Log("OleDbError", ex.Message);
                }
                if(con.State == System.Data.ConnectionState.Open)
                {
                    using (OleDbCommand cmd = new OleDbCommand("DELETE * FROM ArcadeDatabase WHERE uName ='" + button.CommandName + "';", con))
                    {
                        try
                        {
                            cmd.ExecuteNonQuery();
                        }
                        catch (Exception ex)
                        {
                            helper.Log("OleDbError", ex.Message);
                        }
                    }
                }
                con.Dispose();
            }
            path = "";
        }
        catch (Exception ex)
        {
            helper.Log("Admin", ex.Message);
        }
    }
2
  • There seems to be nothing wrong with this code. You need to provide at least the code for the DeleteUser event. Commented Jan 15, 2017 at 11:17
  • I have edited my question and it now contains the DeleteUser code :) But as I said, I placed a breakpoint and it doesn't even execute. Commented Jan 15, 2017 at 11:28

1 Answer 1

2

The event handler for dynamic controls need to be registered during Page_Load / Page_Init events to be triggered (see this link).

So, You have to add your Delete button and its event handler in page_load or init. to find ID of the control which cause postback in Page_Init event, see this


UPDATE:

OK, i add this code to proof it can be done without problems.

To see how it works: create a new Web Form and paste the following HTML & Code-Behinds into it. Then run the app and type some name in Search TextBox (eg: John or Ali) and press Search Button to filter the results.

public partial class _Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string searchName = "";
        if (SearchTextBox.Text != "") //if (this.GetPostBackControlUniqueID() == Search.UniqueID) //Search button is clicked! 
        {
            searchName = SearchTextBox.Text;
        }
        addTable(searchName);
    }

    void addTable(string searchName)
    {
        string[] data = new[] { 
             "John, false, usrJohn"
            ,"Alex, false, usrAlex"
            ,"Ali,  true,  usrAli" 
        };

        //using (OleDbDataReader reader = cmd.ExecuteReader())
        //{
            Table table = new Table(); table.CellPadding = 10;
            TableRow row;
            TableCell cell;
            Label label;

            foreach(string dataItem in data) //while (reader.Read())
            {
                string[] reader = dataItem.Split(',');
                if (reader[0].IndexOf(searchName, StringComparison.OrdinalIgnoreCase) < 0) continue; //search not found (in real app, you use sql where clause for this, but this is just for test)

                row = new TableRow();
                cell = new TableCell();
                label = new Label();

                label.Text = reader[0].Trim(); //reader.GetString(0);
                cell.Controls.Add(label);
                cell.BorderStyle = BorderStyle.Solid;
                row.Cells.Add(cell);

                cell = new TableCell();
                label = new Label();

                label.Text = reader[1].Trim(); //reader.GetBoolean(1).ToString();
                cell.Controls.Add(label);
                cell.BorderStyle = BorderStyle.Solid;
                row.Cells.Add(cell);

                cell = new TableCell();
                LinkButton button = new LinkButton();

                button.Text = "Delete";
                string uName = reader[2].Trim();
                button.ID = uName; //(string)reader["uName"];
                button.CommandName = uName; //(string)reader["uName"];
                button.Click += new EventHandler(DeleteUser);

                cell.Controls.Add(button);
                cell.BorderStyle = BorderStyle.Solid;
                row.Cells.Add(cell);

                table.Rows.Add(row);
            }

            table.Style.Add(HtmlTextWriterStyle.MarginLeft, "auto");
            table.Style.Add(HtmlTextWriterStyle.MarginRight, "auto");

            TableHolder.Controls.Add(table);
        //} //end using OleDbDataReader reader
    }

    protected void Search_Click(object sender, EventArgs e)
    {
        //addTable(SearchTextBox.Text); //already done in Page_Load
    }

    protected void DeleteUser(object sender, EventArgs e)
    {

        LinkButton button = (LinkButton)sender;
        //using (OleDbCommand cmd = new OleDbCommand("DELETE * FROM ArcadeDatabase WHERE uName ='" + button.CommandName + "';", con))
        string sql = "DELETE * FROM ArcadeDatabase WHERE uName ='" + button.CommandName + "';";
        //execute the sql ... (in real app)

        TableHolder.Controls.Add(new LiteralControl("The sql was: " + sql));
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToString("HH:mm:ss");
    }


} //end class

And this is the helper extension method to Get UniqueID of PostBack Control:

// ***********************************************************************
public static class MyWebPageExtensions
{

    public static string GetPostBackControlUniqueID(this Page page)
    {
        if (!page.IsPostBack)
            return string.Empty;

        Control control = null;

        string controlName = page.Request.Params["__EVENTTARGET"]; //this method works only for link buttons which use javascript: __doPostBack(...) and not input type=submit buttons. Note: it is also available in Request.Form collection but this doesn't require to loop over Form.
        if (!String.IsNullOrEmpty(controlName))
        {
            control = page.FindControl(controlName);
        }
        else
        {
            // __EVENTTARGET is null, the control is a button (not javascript linkButton), we need to iterate over the form collection to find it
            foreach (string id in page.Request.Form)
            {
                // handle ImageButton they having an additional "quasi-property" in their Id which identifies mouse x and y coordinates
                if (id.EndsWith(".x") || id.EndsWith(".y"))
                {
                    string id2 = id.Substring(0, id.Length - 2);
                    control = page.FindControl(id2);
                }
                else
                {
                    control = page.FindControl(id);
                }

                if (control is IButtonControl) break;

            }
        }

        return control == null ? String.Empty : control.UniqueID;
    }

}
Sign up to request clarification or add additional context in comments.

11 Comments

Thanks but I am not really sure how I should proceed from here. I have a mode which is the normal mode, meaning the user is not looking up anything in the database and I also have a mode saying that the user IS looking up someone in the database, how can I know, on page load which mode is currently triggered? How do I know how much entries came up? How do I know the name of the user in the table and the exact location to add that button to on page load?
as i saw already in your code, with help of this button.CommandName = (string)reader["uName"]; you know which user shall be deleted.
Oh, so I only need to register the event in page load, now I get it. But how do I know how many buttons need to be registered? How can I loop through them? I am not asking you to write a code, just for a direction.
but you already write basic part of such code: using (OleDbDataReader reader = cmd.ExecuteReader()) ... while (reader.Read()) ... LinkButton button = new LinkButton(); button.Text = "Delete"; ...
That's correct, but how do I access it from the page load?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.