I have an htmlgeneric control and on run time i am adding control in it but when i click on any button then added controls disappear.
Dynamically created controls need to be created on every post back. You also need to give them an ID if you want to maintain and restore their ViewState.
For example, this will show the TextBox the first time the page is loaded, but on any subsiquent page loads, the control will be missing:
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
TextBox newControl = new TextBox()
{
ID = "newControl"
};
SomeControl.Controls.Add(newControl);
}
}
However, if you create the control on every postback with the same Id, then the control will be maintained with it's Text:
protected void Page_Init(object sender, EventArgs e)
{
TextBox newControl = new TextBox()
{
ID = "newControl"
};
SomeControl.Controls.Add(newControl);
}
Here's a good article about dealing with dynamic controls.
Related
I have a DropDownList and a CheckBox on my web form. After the DropDownList is clicked and this event is posted back to the server. DropDownList_SelectedIndexChanged event is called on the server side. Inside that event handler, I have CheckBox.Checked = true, But I couldn't make the page on the client side to reflect this change (CheckBox.Checked = true). How do I achieve this? Or am I in the wrong direction to use the DropDownList's event handler to update the CheckBox because the page firstly reloads and then DropDownList_SelectedIndexChanged is called?
Page load method:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.DropDownList1.Items.Clear();
AddItemsToDropDownList();
}
}
DropDownList selected index changed event handler:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
var selected = this.DropDownList1.SelectedItem.Text;
CheckBox checkBox = GetCheckBoxToBeSetByText(selected);
checkBox.Checked = true;
}
OK. Found the issue. Actually there is nothing wrong with the code in my original post. But to make a smallest sample when I posted, I removed some "extra" code. The below is the "complete" code (OK, fine, I still removed some code). As you can see, I put the CheckBox into a static Dictionary. Each time the SelectedIndexChanged event handler is called, it's modifying the CheckBox in that static Dictionary, which means it's modifying the CheckBox object created from the last session? (still not clear here) Looks like each time when a postback message is received, a new set of CheckBox objects are created. Bear with me if this is known to everybody here already because I only have two days of experience on this web development thing up to today.
private static Dictionary<Environment, CheckBox> EnvironmentsCheckBoxes;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
EnvironmentsCheckBoxes = new Dictionary<Environment,CheckBox>();
EnvironmentsCheckBoxes.Add(Environment.Dev1, this.Dev1_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.Dev2, this.Dev2_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.QA, this.QA_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.QA2, this.QA2_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.Demo, this.Demo_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.Prod, this.Prod_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.UAT, this.UAT_CheckBox);
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
var selected = this.DropDownList1.SelectedItem.Text;
if (selected == "Dev1")
{
EnvironmentsCheckBoxes[Environment.Dev1].Checked = true;
}
else if (selected == "Dev2")
{
...
}
...
}
In .NET i have a gridview which has to display on the mainpage with default settings. So i put it in pageload code. In the same page i have a "List" button; people choose date etc. and when they press the button gridview loads data from another stored procedure. I put that code under List button event. But after people press List button and gridview comes with the needed data, if they press something else (because of page refresh itself) gridview turns back to default settings.
How do i keep the gridview with wanted data?
protected void Page_Load(object sender, EventArgs e)
{
opsbelgegridview.DataSource = DB.OpsHavuzGetir();
opsbelgegridview.DataBind();
protected void listelebtn_Click(object sender, EventArgs e)
{
opsbelgegridview.DataSource = DB.OpsHavuzDetayListeleBtn(tarih1.ToString("yyyy-MM-dd"), tarih2.ToString("yyyy-MM-dd"), durumdd.SelectedItem.Text.ToString(), islemtipdd.SelectedItem.Text.ToString());
opsbelgegridview.DataBind();
You can use IsPostBack() and only load the initial grid on the first load of the page. Then if the grid data changes it will stay.
private void Page_Load()
{
if (!IsPostBack)
{
opsbelgegridview.DataSource = DB.OpsHavuzGetir();
opsbelgegridview.DataBind();
}
}
I have seen two few other posts related to this but I have doubts related to my code. So kindly bear with me.
I have user control which has a text boa and a drop down list and few custom validators.
The user control is added dynamically through a code.
I am using follwoing code to load the dropdownlist inside user control itself
protected void Page_Load(object sender, EventArgs e)
{
ddl_RRC.DataSource = dicRC_Desc;
ddl_RRC.DataTextField = "value";
ddl_RRC.DataValueField = "key";
ddl_RRC.DataBind();
txtRC.Text = Request.Form[txtRC.UniqueID]; //To retain the value of text box
}
I am adding the user control dynamically on Page_Init
protected void Page_Init(object sender, EventArgs e)
{
if (GetPostBackControl(this) == "btnNewRow")
{
custControlCountID++;
}
for (int i = 0; i < custControlCountID; i++)
{
RejRow customControl = (RejRow)LoadControl("~/RejRow.ascx");
customControl.ID = "rejRow" + i;
divHolder.Controls.Add(customControl);
}
}
Viewstate is enabled for both the text box and drop down list.
As I am using the same ID while adding the controls in Page_Init, why the controls are not getting the values from viewstate?
I think the only problem is that you have you're databinding the DropDownList on every postback from Page_Load. Just check the IsPostback-property, e.g.:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
ddl_RRC.DataSource = dicRC_Desc;
ddl_RRC.DataTextField = "value";
ddl_RRC.DataValueField = "key";
ddl_RRC.DataBind();
}
txtRC.Text = Request.Form[txtRC.UniqueID]; //To retain the value of text box
}
However, i'm not sure why you need to set the TextBox.Text property from the form-fields since it should store it's Text also in ViewState.
I have a blank user control (child) and during Page_Load i create some text boxes and a button. I also add an event to the button.
I then load that user control dynamically from a placeholder in another usercontrol (parent).
Both controls are rendered correctly but when i click on the button, the event isnt fired.
Any ideas on how to handle the event?
Child code:
protected void Page_Load(object sender, EventArgs e)
{
/*... other user controls ..*/
UpdateButton = new LinkButton();
UpdateButton.ID = "buttonid";
UpdateButton.Text = "text";
UpdateButton.Click += new EventHandler(UpdateButton_Click);
this.Controls.Add(UpdateButton);
}
protected override void Render(HtmlTextWriter writer)
{
for (int i = 0; i < this.Controls.Count; i++)
{
this.Controls[i].RenderControl(writer);
}
}
public void UpdateButton_Click(object sender, EventArgs e)
{
//Do stuff
}
Parent code:
protected void Page_Load(object sender, EventArgs e)
{
placeholder.Controls.Clear();
ChildControl uc = (ChildControl)LoadControl("~/UserControls/ChildControl.ascx");
placeholder.Controls.Add(uc);
}
If i use the child control directy (ie without the parent the control) the click event is raised and handled nicely. But when i use the parent control, the debugger wont even hit a breakpoint inside UpdateButton_Click().
Thanks in advance.
I think I know what might be happening. In your parent Page_Load you are calling placeholder.Controls.Clear(); This does what you would imagine and clears the control, including any events that have occurred. What happens when remove this line? Do you get an additional one created on each postback?
I put some Image Buttons into my gridview, but I cannot capture the click event. Neither creating a click event, nor creating an OnRowCommand handler in the gridview works.
Clicking the buttons simply postbacks to the current page.
I add my buttons like this:
protected void gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string status = DataBinder.Eval(e.Row.DataItem, "visitstatusuid").ToString();
string visitUID = DataBinder.Eval(e.Row.DataItem, "visituid").ToString();
Color backColor = Color.White;
Color foreColor = Color.Black;
ImageButton b;
switch (status)
{
case "U": // Unallocated
backColor = ColorTranslator.FromHtml("#B2A1C7");
b = new ImageButton();
b.Width = Unit.Pixel(25);
b.Height = Unit.Pixel(30);
b.AlternateText = "Book";
b.ImageUrl = "../../Images/New/booking.gif";
b.ToolTip = "Booking";
b.CommandName = "Booking";
b.CommandArgument = visitUID;
b.CausesValidation = false;
e.Row.Cells[(e.Row.Cells.Count - 3)].Controls.Add(b);
etc.
You'll need to attach the handler when the button is created:
b.Click += MyButtonClickEventHandler;
Edit:
Instead of creating the button in the OnRowDataBound handler, use OnRowCreated.
This ensures the button is recreated on postbacks.
Example:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BindData();
}
}
protected void BindData()
{
// Do your databinding here.
}
protected void MyGridView_RowCreated(object sender, GridViewRowEventArgs e)
{
var b = new ImageButton();
b.AlternateText = "Click Me!";
// Etc.
b.Click += MyButton_Click;
// Add the button to the column you want.
}
protected void MyButton_Click(object sender, ImageClickEventArgs e)
{
// Do your thing...
}
Unless you are adding an event handler elsewhere you would need to set AutoEventWireup="true" in the page directive of your aspx file.
That being said I prefer explicitly wiring events so rather than use AutoEventWireup add this line to your OnInit method:
gridview1.RowDataBound += this.gridview1_RowDataBound;
For your approach using RowDataBound to work, you need to rebind the grid on every page load, and ensure you do it no later than OnLoad in the lifecycle, in order for the click event to be registered in time.
An alternative approach I have had success with is to create a new method for doing the DataGrid button setup, e.g.
void PerformConditionalGridFormatting()
{
foreach (GridViewRow row in gvCaseList.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
... Add your buttons to the cells here
}
}
}
Then you call the method every time you perform a manual databind, and also on every postback i.e. in your OnLoad handler do:
if (Page.IsPostBack) PerformConditionalGridFormatting();
The advantage of this approach is that you don't have to databind on every postback, which saves resources.
create a RowCommand event handler for the gridview and check the command name to see if it's your button triggering it
something to the effect of
void gridview1_RowCommand(object sender, args e)
{
if (e.CommandName == "Booking")
{
// call your desired method here
}
}
Put the binding event of grid in to not post back.