RowDataBound DropDownList - asp.net

I have a RowDataBound event handler that looks like this:
Public Sub CustomersGridView_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles GVHistoricNames.RowDataBound 'RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim hyperlinkUSNHyperlink As HyperLink = CType(e.Row.FindControl("USNHyperlink"), HyperLink)
Dim ddl As DropDownList = CType(e.Row.FindControl("ddlUsercode"), DropDownList)
If ddl.SelectedValue = "" Then 'labLastUserCode.Text = "" Then
hyperlinkUSNHyperlink.NavigateUrl = ""
End If
End If
End Sub
...and a RowCreated event handler that looks like this:
Public Sub CustomersGridView_RowCreated(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles GVHistoricNames.RowCreated 'RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ddl As DropDownList = CType(e.Row.FindControl("ddlUsercode"), DropDownList)
ddl.Items.Add("")
ddl.Items.Add(strUserName)
End If
End Sub
...and a RowUpdating event handler that looks like this:
Protected Sub GVHistoricNames_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GVClearcoreHistoricNames.RowUpdating
Try
Dim ddl As DropDownList = CType(GVHistoricNames.Rows(e.RowIndex).FindControl("ddlUsercode"), DropDownList)
SQLHistoricNames.UpdateParameters("UserCode").DefaultValue = ddl.SelectedValue
Catch ex As Exception
Finally
End Try
End Sub
Please see line three of the RowUpdating event handler. The value of the SelectedValue property is never correct because the RowDataBound event handler is called after the RowUpdating event handler. How do I access SelectedValue? I want to set it as an update parameter.

One of the way could be to look into the actual request data. For example, in GVHistoricNames_RowUpdating code, use
Dim ddl As DropDownList = CType(GVHistoricNames.Rows(e.RowIndex).FindControl("ddlUsercode"), DropDownList)
SQLHistoricNames.UpdateParameters("UserCode").DefaultValue = Request(ddl.UiniqueID)
I often use such work-arounds when the control value is needed before post data could be loaded into control (or when controls are added/bound dynamically at a later event).
EDIT
ASP.NET uses Control.UniqueId to represent name property of corresponding html element. It (as well as ClientID) typically gets constructed by appending control's id to parent's (parent that is naming container) unique id, hence you get different unique ids (and client ids) for multiple drop-down lists in the grid (because each row acts as a naming container)
As far as your problem goes, you are probably creating drop-down list in design time template while you are loading your list items in row created. However, before row-created event is fired, the drop-down list would have been already added to page control tree and its POST events would have been already processed. In such case, there would be no items in the drop-down list at that time to set the selection. Hence the issue.

Related

How to use RadDatePicker inside RadGrid?

Wasn't able to find anything about this situation:
I have two RadDatePicker inside RadGrid for start and end date change
<telerik:RadDatePicker ID="rdpStartDate" Skin="Library" EnableEmbeddedSkins="false" CommandName="StartDateChange" runat="server" />
By itself, they work fine, but now I have a situation when I need to call method when their value has been changed (CommandName was added for this)
I know how to do this outside RadGrid, basically:
Protected Sub rdpStartDateChanged(ByVal sender As Object, ByVal e As Telerik.Web.UI.Calendar.SelectedDateChangedEventArgs) Handles rdpStartDate.SelectedDateChanged
...
...
End Sub
But I wasn't able to do this inside RadGrid, because nothings seems to trigger it.
I tried to catch my command with this (works for buttons at least):
Protected Sub rgLibraryItemCommand(ByVal sender As Object, ByVal e As GridCommandEventArgs) Handles rgLibrary.ItemCommand
But, no, it doesn't see CommandName="StartDateChange"
What I need to do to be able to catch those Date change events if RadDatePicker
is placed inside RadGrid?
You need to identify the control inside the grid which triggers the action. I'm not sure which is the way for Rad to do that but it should be similar this:
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub
So you need to find the events for the DataGridViewRow for Rad and substitute them with the ones cell clicking events. This example should get you started.
Subscribing to an event on a control inside a RadGrid does not work the same way, because there could be multiple copies of the control or even none at all, depending on how many records are in the Data Source. Therefore, in order to subscribe to events on these controls, you have to do it manually after the data is bound, either in the ItemCreated event or ItemDataBound event.
Protected Sub rgLibraryItemCreated(ByVal sender as Object, ByVal e As GridItemEventArgs) Handles rgLibrary.ItemCreated
If TypeOf e.Item Is GridDataItem Then
Dim item As GridDataItem = e.Item
Dim rdpStartDate As RadDatePicker = item.FindControl("rdpStartDate")
AddHandler rdpStartDate.SelectedDateChanged, AddressOf rdpStartDateChanged
End If
End Sub

What is the proper way to use data from a grid view before data binding

I have a user control that creates a grid view of database records. Each record has a checkbox for deleting the record.
My problem is that the the page_load event builds the grid view, then the delete button even fires. The deleteButton_click event is looping over the gridview looking for checked boxes but never finds any because the 'page_load' event just gave me a clean gridview. What is the best way to check for checked boxes before the grid view is re-built? Or can I get the checked values without looking at the grid view?
Protected Sub Page_Load(...) Handles Me.Load
'db calls and other code
gv.DataBind()
End Sub
Protected Sub btnDelAtt_Click(...) Handles btnDelAtt.Click
For Each grdRow As GridViewRow In gvFileViewer.Row
Dim chkBox As CheckBox = CType(grdRow.FindControl("cbItem"), CheckBox)
If chkBox.Checked = True Then 'this is always false thanks to page_load
'code that does not run
end if
next
end sub
As mentioned in the comments, adding !IsPostBack should do it.
You only need to load the grid from the database in the initial call, you don't need to get the data again when post back occurs. You will need to rebind the grid once the delete is over.
Protected Sub Page_Load(...) Handles Me.Load
If(!Page.IsPostBack)
'db calls and other code
gv.DataBind()
End Sub
Protected Sub btnDelAtt_Click(...) Handles btnDelAtt.Click
For Each grdRow As GridViewRow In gvFileViewer.Row
Dim chkBox As CheckBox = CType(grdRow.FindControl("cbItem"), CheckBox)
//Delete your record
end if
next
//Rebind grid
end sub

How to find selected GridView row in page_load event?

I have a page with GridView. The GridView has select button. Normally I use GridView's selected index changed event to do all kinds of operations when user clicks select button. But now I want to do some operations in Page_Load event based on grid view's selected row. Since the Selected_Index_changed event occurs after Page_Load how do I know following things in page load event.
I checked the asp lifecycle and this other question but I dont know how to do this.
How about using a QueryString to transmit which row was selected and then in the Page_Load event get the QueryString parameters? This is an example.
Protected Sub LinkButton1_Command(sender As Object, e As CommandEventArgs)
Dim UserId As Integer = e.CommandArgument 'Here goes whatever value you're trying to pass
Response.Redirect("~/OtherPage.aspx?UserId=" _
& UserId)
End Sub
This is in the OtherPage.aspx
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
UserId = Request.QueryString("UserId")
'Your code
end sub

How do you attach an event handler to a nested custom user control? VB.net

Here's my situation. I have a gridview (gridview1) with a custom user control (UC1) nested in each row. The custom user control has a custom public event called "TaskChanged" that gets raised when a button is clicked. On the parent page(default.aspx), I'm trying to access the user control to attach the event handler to but I'm unsuccessful. Here's how I'm trying to do it.
On the parent page:
Protected Sub GridViewTasks_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridViewTasks.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'Get the User Control
Dim Uc As UserControl = e.Row.FindControl("TaskResourceAssignment")
'Attatch event handler
AddHandler Uc.TaskChanged, AddressOf Uc_OnTaskChanged
End If
End Sub
The problem is that on this line:
AddHandler Uc.TaskChanged, AddressOf Uc_OnTaskChanged
It can't find the control's "TaskChanged" Event (Uc.TaskChanged gets the squiggly lines under it), and running the page just throws an error. I remember a friend being able to do this but he cast his user control as an object and was able to access it. I've tried that with no luck.
The custom control is raising an event and not bubbling an event. I can get it to work by bubbling the event, but I would really like to do it by attaching the event handler to the control. Help anyone??
You need to cast user control to the specific one explicitly, because regular UserControl doesn't have TaskChanged event.
Something like this -
Dim Uc = TryCast(e.Row.FindControl("TaskResourceAssignment"),
TaskResourceAssignment)
The problem is that UserControl doesn't have a TaskChanged event. Neither does the type Control, which FindControl returns.
Your friend cast the Control into a specific control to be able to attach the correct event.
In this case, I believe you're looking for the ITaskService.OnTaskChanged event. So I would try this:
Protected Sub GridViewTasks_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridViewTasks.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'Get the User Control
Dim Uc As UserControl = DirectCast(e.Row.FindControl("TaskResourceAssignment"), ITaskService)
'Attatch event handler
AddHandler Uc.OnTaskChanged, AddressOf Uc_OnTaskChanged
End If
End Sub
I like to use Trycast for this type of work. Replace MyUserControl with the name of your UserControl.
Protected Sub GridViewTasks_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridViewTasks.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'Get the User Control
Dim Uc As MyUserControl = TryCast(e.Row.FindControl("TaskResourceAssignment"), ITaskService)
If Not Uc Is Nothing Then
AddHandler Uc.OnTaskChanged, AddressOf Uc_OnTaskChanged
End If
End If
End Sub

Implementing pager control for gridview?

Is there a way to select the number of records/rows to display in the gridview by a drop down list ?
If you mean a dynamic change of the number of rows based on a DDL selection, sure it can be done.
I would suggest using an AJAX method on the select action that would query the DB for the exact amount of rows and returning. Far too often I've seen a query bring back thousands of rows and the paging etc is done in memory. Much more efficient to just get the rows/page directly from the DB and preserve bandwidth.
Not sure if that is exactly what you were asking, but hope it helps.
You can also use RowCreated to create your Dropdownlist in Codebehind. Have a look at following example(VB.Net):
Private Sub Yourgrid_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles Yourgrid.RowCreated
Select Case e.Row.RowType
Case DataControlRowType.Pager
Dim ddlPager As New DropDownList
ddlPager.ID = "DdlPager"
ddlPager.AutoPostBack = True
ddlPager.ToolTip = "Change Pagesize"
ddlPager.Items.Add("5")
ddlPager.Items.Add("10")
ddlPager.Items.Add("25")
ddlPager.Items.Add("50")
ddlPager.Items.Add("100")
ddlPager.SelectedValue = "10"
AddHandler ddlPager.SelectedIndexChanged, AddressOf Me.PageSizeChanged
e.Row.Cells(0).ColumnSpan -= 1
Dim td As New TableCell
Dim span1 As New Label
span1.Text = "Show"
span1.Style("margin-left") = "50px"
td.Controls.Add(span1)
td.Controls.Add(ddlPager)
Dim span2 As New Label
span2.Text = "rows per page"
td.Controls.Add(span2)
e.Row.Cells.Add(td)
End Select
End Sub
Private Sub PageSizeChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ddlPager As DropDownList = DirectCast(sender, DropDownList)
Dim newPageSize As Int32 = Int32.Parse(ddlPager.SelectedValue)
YourGrid.PageSize = newPageSize 'change the PageSize of the Grid'
DataBindYourGrid() 'call the function that Binds your grid to the Datasource'
UpdYourgrid.Update() 'if you use Ajax, update the UpdatePanel of this GridView'
End Sub
On this way you autogenerate the Dropdonwlist on every postback and add it to the Gridview's pager. The code is reusable for any GridView.

Resources