Dynamically added link button disappeared on button click leaving an empty column - asp.net

The datagrid reads from several xml files, so I create the columns dynamically, and added a templatefield as the last column.
A link button is added in the templatefield using RowDataBound.
Private Sub GridItem_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridItem.RowDataBound
Try
If e.Row.RowType = DataControlRowType.DataRow Then
Dim linkb As New LinkButton
linkb.Text = "Delete"
linkb.ID = "LinkDeleteItem"
linkb.OnClientClick = "javascript:DeleteItem('" & Convert.ToString(e.Row.RowIndex) & "')"
e.Row.Cells(GridItem.Columns.Count - 1).Controls.Add(linkb)
End If
Catch ex As Exception
lblMessage.Text = ex.Message
End Try
End Sub
Everything works fine.
But when I click a button outside the gridview, to open a window to add a new item to the grid, the linkbuttons disappear. But the column is still there.
If I just close the new window without saving a new data (which will prompt the grid to rebind), the column remains empty. I had to reload the gridview for the linkbuttons to appear.
Is it because the linkbuttons are created on rowdatabound? How should I solve this?

This is happening because the OnRowDataBound event of GridView is NOT called on next postback. This happens because by default viewstate of GridView is set true i.e. EnableViewState property of Gridview is true. When ViewState is on, Gridview stores data from the same and OnRowDataBound event is not called. Also, at this point View state will not be applied for your linkButtons as they aren't created in page_load.
Try setting EnableViewState property to false for your gridview:
<asp:GridView ID="CustomersGridView"
OnRowDataBound="CustomersGridView_RowDataBound"
EnableViewState="false"
.... />
OR you can also bind your GridView in page_Load as:
protected void Page_Load(object sender, EventArgs e)
{
CustomersGrIdView.DataBind();
}
Now after every postback your OnRowDataBound event will be called and hence the LinkButtons will be available everytime.
NOTE: Setting EnableViewState property to false for gridview can be a bad practice to an extent, especially in scenarios of heavy data usages. Same goes for Binding gridview every time.
When using dynamic controls, they exist only until the next postback.ASP.NET will not re-create a dynamically added control. If you need to re-create a control next time too on postback, you should perform the control creation in the PageLoad event handler.
This will give you benefit of using view state with your dynamic control. Even though view state is normally restored before the Page.Load event, if you create a control in the handler for the PageLoad event, ASP.NET will apply any view state information that it has after the PageLoad event handler ends.

Related

wont add updated check boxes from gridview to arraylist

On my aspx page I have a gridview template that when it is rendered has 100 - 200 rows and each row has a check box.
When the page loads 5 check boxes are automatically checked. If I manually check another 3 then press the submit button, then loop through all the gridview rows to find out which rows had a checked box then it still remembers the original 5. How do I make it remember the updated 8?
Protected Sub mySubmitButton_Click(sender As Object, e As EventArgs)
Dim myArray As ArrayList = New ArrayList()
For Each myRow As GridViewRow In MyGridview.Rows
If CType(myRow.FindControl("MyCheckbox"), CheckBox).Checked Then
myArray.Add(MyGridview.DataKeys(MyRow.RowIndex).Value)
End If
Next
'add to DB myArray
End Sub
I tried this on the gridview in the asp.net and it made no difference
ViewStateMode="Disabled" and ViewStateMode="Enabled"
Thanks for the help
Is the ViewState enabled on the GridView?
Have you got the logic to load your Grid in the Page_Load event, if so add it in if(!IsPostBack)

get selected index of databound list control on user control

I have a radiobuttonlist that lives on a user control. This user control lives in a repeater on a parent user control, and that user control lives on a page with a submit button.
So something like this:
<page>
<UserControl1>
<Repeater>
<UserControl2>
<radiobuttonlist>
</UserControl2>
</Repeater>
</UserControl1>
<Submit button />
</page>
The radiobuttonlist is dynamically populated in the code-behind of UserControl2. The problem is that when I submit the form, I need to access the SelectedValue of the radiobuttonlist, and that value is always empty. Even if I first fire the methods that populate the radiobuttonlist, the selectedvalue of the RBL is empty. I have a SelectedIndexChanged event handler on the RBL, but it never fires.
What do I need to do to be able to get the SelectedValue of the radiobuttonlist when I cause the parent page to postback?
I got it working. I guess it was an order of operations issue. The fix was to dynamically declare the event handler of the radiobuttonlist in the OnInit() of UserControl2.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
rblOptions.SelectedIndexChanged += new EventHandler(ctrlOptions_SelectedIndexChanged);
}
Once I did that, the event started firing, even though I was re-instantiating the UserControl on postback. Since the event was firing, I was able to obtain the Selected Index without needing to keep it in ViewState.
When you post your datas, you re-bind your datas so you erase your selected event or values.
Try with this code in your Page_Load (Of your User Control)
If(! IsPostBack)
{
//You build RadioButtonList
}
And persist your datas with ViewState, EnableViewState="true"

Dynamic controls in postback

I'm trying to add a set of LinkButtons to the PagerRow of a GridView in an UpdatePanel. I'm using the RowCreated event to instantiate and add these. The problem I have is the click handlers are only fired the second time.
I create the LinkButtons using
Protected Sub grd_RowCreated(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If (e.Row.RowType = DataControlRowType.Pager) Then
Dim pageSizer = New GridViewPageSizer(grdItems)
e.Row.Cells(0).Controls.AddAt(0, pageSizer)
End If
End Sub
To create the LinkButtons themselves, I'm using
Dim lnkSize = New LinkButton() With { _,
.Text = size.ToString(), _
.CommandArgument = size.ToString(), _
.ID = "pageSizer" & size
}
AddHandler lnkSize.Click, AddressOf lnkPageSize_Click ' an EventHandler which just changes pagesize based on CommandArgument
liSize.Controls.Add(lnkSize)
The GridViewPageSizer inherits HtmlGenericControl and adds an event handler for the click of each button. On every postback, the pager row is recreated, so the old buttons are replaced with a new set and their event handlers only fire on the second click. If I check for !IsPostBack, the buttons disappear after the first click. I've tried rebinding the grid after the buttons are clicked and the pagesize changes but the same thing happens. Is there a way around this?
In order for an EventHandler to trigger correctly, you need to bind it on Page Init/PreInit.
Make a session indicator and on postback, check that session on Page Init.
If that satisfies the condition, instead of recreating it on RowCreated Event, recreate the controls together with the Events on Page Init instead.
This time, events will trigger correctly.

dynamic columns disappears after postback

I have a GridView with some BoundFields and two TemplateFields. In these two TemplateFields, I dynamically create UserControls containing a DropDownList and a TextBox, which users can modify.
When I try to get the values of the controls after a PostBack, the values in BoundFields are still there but my dynamic controls disappears. I can create them again but it won't get the user's values... How can I get these values before they're lost?
Here's some of my code:
In the RowDataBound event:
Select Case type
Case "BooleanBis"
e.Row.Cells(2).Controls.Clear()
Dim list1 As BooleanBisList = New BooleanBisList(avant, False)
e.Row.Cells(2).Controls.Add(list1)
e.Row.Cells(4).Controls.Clear()
Dim list2 As BooleanBisList = New BooleanBisList(apres, True)
e.Row.Cells(4).Controls.Add(list2)
Case "Boolean"
e.Row.Cells(2).Controls.Clear()
Dim list3 As BooleanList = New BooleanList(avant, False)
e.Row.Cells(2).Controls.Add(list3)
e.Row.Cells(4).Controls.Clear()
Dim list4 As BooleanList = New BooleanList(apres, True)
e.Row.Cells(4).Controls.Add(list4)
End Select
In my button click event, I try to get the user control :
Case "String"
temp.ChampValeurApres = DirectCast(Tableau1.Rows(i).Cells(selectedColumn).Controls(1), TextBox).Text
but i get the error that it doesn't exist.
You should create dynamic controls in RowCreated instead of RowDataBound because this event gets fired on every postback whereas RowDataBound only will fire when the GridView gets databound to it's DataSource.
Dynamically created controls must be recreated on every postback with the same ID as before, then they retain their values in the ViewState and events will fire correctly(f.e. a DropDownList's SelectedIndexChanged event).
So you should create them in RowCreated and "fill" them in RowDataBound(f.e. the DropDownList datasource/Items or a TextBox-Text).
I had been using:
EnableViewState="false"
in the GridView attributes. Removing it solved my problem!
I just did
protected void Page_Load(object sender, EventArgs e)
{
if (!(Page.IsPostBack))
{
// Put the selected items which u want to keep on postback
}
else
{
//regenerate auto created controls
}
}
and it worked as well

control with ID 'GridView1' could not be found for the trigger in UpdatePanel 'UpdatePanel1'

I have two gridview in update panel and m adding entries from one gridview to another on selectedIndexChanged event what m trying to do is updating update panel on this event selectedindexchanged ...but my gridview is inside accordian control so it does not get initialized and hence i get this error .....
control with ID 'GridView1' could not be found for the trigger in UpdatePanel 'UpdatePanel1'
Anybody knows solution?
I haven't had a chance to test this yet, but this might be what you're looking for. It's possible that you need to dynamically add the trigger at Page_Init. Like this:
protected void Page_Init()
{
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.EventName = "SelectedIndexChanged";
trigger.ControlID = GridView1.UniqueID.ToString();
UpdatePanel1.Triggers.Add(trigger);
}
Try adding that to your code-behind contemporary to Page_Load() and removing the trigger from your mark-up.

Resources