0

I'm quite new to ASP.NET and I need your help.

I'm programming on an application which should help to fix frequent issues. Users can click the displayed cases if it describes their problem. The application searches for more cases or displays a possible solution.

Now what I need for this is some code which creates the buttons dynamically. I googled some ideas and created some code, however I was not able to get it to work.

It works to create the first selection of buttons with the Default_Load method. Also the OnClick event (ButtonClick_System) works fine which means I get the next selection. From here it starts messing around. The dynamic buttons created in ButtonClick_System don't have a working OnClick action.

Instead of proceeding with ButtonClick_Question (because of btn_system.Command += ButtonClick_Question; in ButtonClick_System) it seems like it just loads the homepage (maybe something wrong with Page_Load?).

The application should do ButtonClick_Question until no more datasets available in database.

I got the following code:

using System;
using System.Configuration;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Data;
using Oracle.DataAccess.Client;

namespace Application
{
    public partial class _default : System.Web.UI.Page
    {
        // Variables
        private string app_name = "Application";

        // ----- Page_Load ----- //
        protected void Page_Load(object sender, EventArgs e)
        {
                Default_Load();
                Session["Application"] = app_name;
        }

        // ----- Methods ----- //
        // Load homepage
        public void Default_Load()
        {
            pnl_default.Visible = true;
            pnl_content.Visible = false;
            HtmlGenericControl html_default = new HtmlGenericControl();
            html_default.TagName = "div";

            string cmdString = "(...)";
            DataTable dtSystems = OraQueryData(cmdString);
            foreach (DataRow dtRow in dtSystems.Rows)
            {
                int system_id = Convert.ToInt32(dtRow["SYSTEM_ID"]);
                string system_name = Convert.ToString(dtRow["SYSTEM_NAME"]);
                var btn_system = new Button
                {
                    ID = "btn_" + system_name,
                    Text = system_name,
                    CssClass = "sys_buttons"
                };
                btn_system.Command += ButtonClick_System;
                btn_system.CommandArgument = Convert.ToString(system_id);
                html_default.Controls.Add(btn_system);
            }
            plh_default.Controls.Clear();
            plh_default.Controls.Add(html_default);
        }

        // Button OnClick Events
        protected void ButtonClick_System(object sender, CommandEventArgs e)
        {
            pnl_default.Visible = false;
            pnl_content.Visible = true;
            HtmlGenericControl html_questions = new HtmlGenericControl();
            html_questions.TagName = "div";

            int system_id = Convert.ToInt32(e.CommandArgument);
            string cmdString = "(...)";
            DataTable dtQuestions = OraQueryData(cmdString);

            foreach (DataRow dtRow in dtQuestions.Rows)
            {
                string question_id = Convert.ToString(dtRow["FRAGE_ID"]);
                string question_text = Convert.ToString(dtRow["FRAGE_TEXT"]);
                var btn_system = new Button
                    {
                        ID = "btn_question" + question_id,
                        Text = question_text,
                        CssClass = "quest_buttons"
                    };
            btn_system.Command += ButtonClick_Question;
            btn_system.CommandArgument = Convert.ToString(system_id);
            html_questions.Controls.Add(btn_system);
            }
            plh_content.Controls.Clear();
            plh_content.Controls.Add(html_questions);
        }

        protected void ButtonClick_Question(object sender, CommandEventArgs e)
        {
            pnl_default.Visible = false;
            pnl_content.Visible = true;
            HtmlGenericControl html_ChildQuestions = new HtmlGenericControl();
            html_ChildQuestions.TagName = "div";

            int parent_id = Convert.ToInt32(e.CommandArgument);
            string cmdString = "(...)";
            DataTable dtChildQuestions = OraQueryData(cmdString);

            foreach (DataRow dtRow in dtChildQuestions.Rows)
            {
                string question_id = Convert.ToString(dtRow["FRAGE_ID"]);
                string question_text = Convert.ToString(dtRow["FRAGE_TEXT"]);
                var btn_system = new Button
                {
                    ID = "btn_question" + question_id,
                    Text = question_text,
                    CssClass = "quest_buttons"
                };
                btn_system.Command += ButtonClick_Question;
                btn_system.CommandArgument = question_id;
                html_ChildQuestions.Controls.Add(btn_system);
            }
            plh_content.Controls.Clear();
            plh_content.Controls.Add(html_ChildQuestions);
        }

        // ----- Oracle Data Query Methods ----- //
        // Create and execute query on database
        public static DataTable OraQueryData(string cmdString)
        {
            string conString = ConfigurationManager.AppSettings["Connection"];
            OracleConnection oraCon = new OracleConnection(conString);
            OracleCommand oraCmd = new OracleCommand(cmdString, oraCon);
            OracleDataAdapter oraDtAd = new OracleDataAdapter(oraCmd.CommandText, oraCon);
            DataTable dt = new DataTable();
            oraCon.Open();
            oraDtAd.Fill(dt);
            oraCon.Close();
            return dt;
        }
    }
}
3
  • 1
    Did you try creating the buttons in the PreInit event of the Page? Commented Oct 24, 2016 at 9:42
  • Indeed, in my experience PreInit is the only place where you can safely add dynamic Controls, otherwise ViewState does not know about the controls added. Commented Oct 24, 2016 at 10:00
  • I didn't try that yet. Do you have some example how to do this? Commented Oct 24, 2016 at 11:10

1 Answer 1

3

If I've understood the issue correctly I think you're using the wrong controls for the wrong usages.

What I'd suggest you need to do is bind the collection of FAQ records to a repeater or some other data set display control. You can then have an event on the repeater which can handle which record ID has been clicked, post back with that value and refresh the collection of data from that (maybe in another repeater). Don't dynamically create buttons and bind events to them otherwise you will end up in a mess.

Hope this helps.

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

2 Comments

Thanks for this post, I'll try that and give some feedback.
Sorry for this late feedback. I'm still creating my buttons dynamically from code behind. The reason why it did not work was simple. After the lifecycle of the ASP.Net page all my previous buttons were lost. Also their link to the OnClick EventHandler. I got to make sure that my buttons are loaded at the same time as the EventHandler gets called. Thanks anyway!

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.