GridView Row Redirect to Pre-filled DetailsView on Button Click - asp.net

Background:
I have a GridView which gets populated from an SqlDataSource via DataSourceID. The rows show some summary data from an SQL View. Upon clicking a row, I would like to take my user to another page with a DetailsView control which gets populated with the full set of values from the DB related to the row clicked. My user should be able to edit the data, download files associated with the record, and create a new record of a different type based on said data.
Error:
All examples that I've found for Clickable GridView rows end up with some variation of the error Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%# Page EnableEventValidation="true" %> in a page.
Naturally, I do not want to expose my site to vulnerabilities by disabling event validation. I need to be able to grab the Primary key of the clicked row's associated record and perform operations on that data on a subsequent page, probably via a DetailsView. I suspect my errors are a result of my setup, which is why I included those details.
My Questions Are:
How do I capture the Primary Key of clicked row?
How do I, onclick, forward to a "details" page with a pre-filled form containing data from the row record that was clicked?
HERE'S THE COMPLETE SOLUTION
**thanks again to Icarus' help
'Fetch the DataKey ("ID"), seems to work
Protected Sub RowBind(ByVal sender As Object, ByVal e As GridViewRowEventArgs) _
Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString()
End If
End Sub
'Handle button click
Protected Sub RowClick(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) _
Handles GridView1.RowCommand
If e.CommandName = "Select" Then
'Add to session variable; translate the index of clicked to Primary Key
Session.Add("DetailsKey", GridView1.DataKeys(e.CommandArgument).Value.ToString)
Response.Redirect("details.aspx")
End If
End Sub
And My Markup
<asp:GridView ID="GridView1" runat="server" DataSourceID="GridView1SDS"
DataKeyNames="ID" AllowPaging="True" AllowSorting="True">
'<!-- Styling -->
<Columns>
<asp:ButtonField ButtonType="Button" Text="Details" CommandName="Select" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="GridView1SDS" runat="server"
ConnectionString="<%$ ConnectionStrings:dbConnectionString %>"
SelectCommand="select * from viewRequestQueue">'<!-- An SQL View -->
</asp:SqlDataSource>
Forwarded Page VB & Markup
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
GridView2SDS.SelectCommand = "select * from viewRequestQueue where ID = " _
+ Session.Item("DetailsKey").ToString
End If
End Sub
<asp:DetailsView ID="GridView2" runat="server" DataSourceID="GridView2SDS">
'<!-- Styling -->
</asp:DetailsView>
<asp:SqlDataSource ID="GridView2SDS" runat="server"
ConnectionString="<%$ ConnectionStrings:dbConnectionString %>">
</asp:SqlDataSource>
Also, please note that if the SelectCommand for your DataSource is handled in the codebehind, that means the DataBind will overwrite your <Columns> in the markup. To get around this, you should define the columns in the code behind before the DataBind. So say I wanted to add another ButtonField column to my forwarded page (notice the SelectCommand is not provided in the markup), I added the following before the setting the SelectCommand and doing the DataBind:
Dim id As New ButtonField()
id.ButtonType = ButtonType.Button
id.Text = "Load"
id.CommandName = "Select"
PubDetails.Columns.Add(id)

You need to declare the KeyNames of the items you are binding on your markup. For example:
<asp:GridView id="grid" runat="Server" DataSourceID="YourSQLDataSource" DataKeyNames="ID,Name" />
In your case, you seemed to be handling the OnRowDataBound event. You can do this to grab the key inside RowBound:
If e.Row.RowType = DataControlRowType.DataRow Then
Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString() 'get the datakey
End If
Your second question is difficult to answer because you did not specify how you want the user to be redirected, if from the client side using Javascript or from the Server side. You also did not specify how do you expect to populate the details on the Details page. Do you expect to read a parameter from the URL and use it to get the record details from the database?

Related

ASP.NET bound hyperlink as SQL Server stored procedure parameter?

I've currently got a gridview that is populated with summary data. I've created a hyperlink from a bound field labeled ticket_num. What I'm wanting to accomplish is to click the hyperlink and have that call a stored procedure. I need to pass that text of that hyperlink into the stored procedure in SQL Server. So the flow is something like this...
User clicks link
The text of that hyperlink is passed into a parameter for the SQL Server stored procedure to use
Call the stored procedure and display results on new page
Any ideas? The stored procedure is created, connection into the server via ASP.NET is created. Everything works thus far but I can't figure this piece of it out.
Well, since you want some code to execute, then LITTLE reason exists to use a hyper-link, since that not what you need nor want.
You don't mention if you prefer to "hide" the URL and hyper link anyway? (often for security, this is not all such a bad idea).
so, if you need to hide/not show/don't want the value in the grid, then our simple button click can get the row id of the grid (also hidden), and then get the value, and then pass to sql server.
Or, you can add to the button the URL or value to the button - just use command argument. That way you don't have to hit the database again based say on row PK id.
So, here is a simple grid. I have the URL as a row on the grid, but lets also shove/put it into the button for you to see how this works.
So, simple grid:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
<asp:BoundField DataField="Fighter" HeaderText="Fighter" />
<asp:BoundField DataField="Engine" HeaderText="Engine" />
<asp:BoundField DataField="Thrust" HeaderText="Thrust" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Preview">
<ItemTemplate>
<asp:Image ID="Image2" runat="server" ImageUrl = '<%# Eval("ImagePath") %>' Width="140" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="View" CssClass="btn"
CommandArgument = '<%# Eval("ImagePath") %>' OnClick="cmdView_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And our code to load up the above:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGridF()
End If
End Sub
Sub LoadGridF()
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * FROM Fighters", conn)
conn.Open()
Dim rstData = New DataTable
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
End Sub
And now we have this:
Note how we have a PLAIN JANE button - after all, it not really a hyper link we need, is it?
So, for our button click event, we have this:
Protected Sub cmdView_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
Debug.Print("Row index click = " & gRow.RowIndex)
' get database row PK id
Dim iPK As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
' now we have database row PK - walk the dog, do payroll processing
' do ANYTHING we want like get the database row etc.
Debug.Print("Data base row PK id = " & iPK)
Debug.Print("Command button arugment = " & btn.CommandArgument)
End Sub
And output is then:
So, you can see, we did not need (or want a hyper link), but a simple button, and that click event can:
get any value from the given grid row
get the database PK id (hidden - never exposed to client side (good security).
get the row click index
get parameters passed to button
And we can use gRows.Cells() to get the other row values (for data fields)
And of course gRow.FindControl("ctrl name") for templated columns.

How to handle nulls with Eval

I can have a record with all filled in fields and then without an SO_ID or SO_Num. I want my eval to be able to handle these and just return a '-' in the grid column when this happens while still returning all other data for that row. I've tried other solutions online and couldn't find one that works.
<dx:GridViewDataColumn FieldName="SO_Num" VisibleIndex="19" runat="server" Caption="Sales Order Number">
<DataItemTemplate>
<a id="clickElement" href="../sales/order/view.aspx?ID=<%# Eval("SO_ID").ToString()%>"><%#Eval("SO_Num").ToString()%></a>
</DataItemTemplate>
</dx:GridViewDataColumn>
You can use a in-line "iif(), and thus this:
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:TextBox ID="txtCity" runat="server"
Text = '<%# IIf(IsDBNull(Eval("City")), "-", Eval("City")) %>'
></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
So, in above, if say Eval("City") is null, then we display a "-", else we display Eval("City")
Edit: display of values and some button to click and navgate are DIFFERENT!!
As I pointed out, if you need a Eval() in the GridView, and want to convert a null say into a "-", then do that (but, I fail to see why I would want to display some "-" in the GV. Why do that?? Seems rather strange to me?
However, if you have a button on the GV row, and you want to click on that button to jump or navigate to some other page? Fail to see how such a button click and navigate has ANY REALATIONSHIP to what we display? Why are the two concepts connected? I fail to see any sensible logic here?
If you want to drop in a pane jane button, or even a link button (no difference here), then wire up a click event for that given button you drop in.
so, say in our GV, we drop in a button to view a given row of data. Say this GV with hotels, and a button.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
CssClass="table table-hover" Width="50%"
DataKeyNames="ID" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:TemplateField HeaderText="Hotel Name">
<ItemTemplate>
<asp:Label ID="txtHotel" runat="server"
Text='<%# Eval("HotelName") %>' >
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="View" CssClass="btn "
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="pagenavi" />
</asp:GridView>
so, we just dropped in a plane jane button for operations on that one row.
So, our code to load is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
End If
End Sub
Sub LoadGrid()
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
"SELECT * from tblHotelsA ORDER BY HotelName"
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
Dim rst As New DataTable
rst.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rst
GridView1.DataBind()
End Using
End Using
End Sub
And our results are now this:
Ok, so now lets wire up that plane jane button click.
As a normal rule, you can double click on a button to build the click event, or bring up the property sheet, choose events tab/section, and then add the click event. However, since the button is in the GV, then we have to add the click event this way (in the markup).
Type in OnClick=, and when you hit the "=" sign, intel-sense will popup a dialog to create the event.
You get this:
So, we select create new event. Don't seem like anything occurred, but flipping to code behind, we have a click event stub, and our code thus can be this:
Protected Sub cmdView_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.Parent.Parent
Dim intPKID As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
Debug.Print("Row click index = " & gRow.RowIndex)
Debug.Print("Row click database PK id = " & intPKID)
' now do whatever you want with this row information.
' to get values from non templated columns, use cells()
' to get values from tempated columns, use findcontrol
'eg:
' get last name (Boundfield)
Debug.Print("Last name = " & gRow.Cells(1).Text)
' get hotel name - template - "label"
Dim lblHotel As Label = gRow.FindControl("txtHotel")
Debug.Print("Hotel name (label) = " & lblHotel.Text)
End Sub
output:
So, as noted, I fail to see why ANY issue occurs here in regards to some data in a column of the GV being null?
In your case, just navigate based on the button click to anything you want, based on any value you want.
say like this:
<asp:TemplateField HeaderText="View">
<asp:Button ID="cmdView" runat="server" Text="View" CssClass="btn "
OnClick= "cmdView_Click"
CommandArgument = '<%# Eval("SO_ID") %>' />
</asp:TemplateField>
And then in code behind:
Protected Sub cmdView_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.Parent.Parent
Dim intPKID As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
Debug.Print("Row click index = " & gRow.RowIndex)
Debug.Print("Row click database PK id = " & intPKID)
Dim intSOID = btn.CommandArgument
Dim strURLJumpTo = "../sales/order/view.aspx?ID=" & intSOID
Response.Redirect(strURLJumpTo)
So, you are free to cook up any URL navagation you want.
NOTE VERY close how I used the data keys feature of the GV. That allowed me to have, use, get, play with the database PK row id, but NEVER do I have to expose or show or have or mess with the database PK id in the actual GV markup.
This is not only nice, but also is a HUGE deal from a security point of view, since then the user, the browser (client side) thus NEVER has to see, or know or can munge or play with the database PK row id - it is 100% server side managed.
And in fact if you SO_ID or whatever values are not in the GV, or the user does not care? Then I would NOT pass the values in the URL as so called "query parms" of the URL, but would in fact pass the values in session() like say this:
Session("OrderID") = intPKID
Response.Redirect("../sales/order/view.aspx")
Then in the page load event of the target page, I do this:
and NEVER EVER forget to check/use the ispostback in your page load event.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
ViewState("OrderID") = Session("OrderID")
Now, in that code behind, and that page, you use this to get/use/have the orederid
dim intOrderID = ViewState("OrderID")
So, on page load (first page, ispostback = false), you transfer the session() value to the ViewState. And you do this since the user might have more then one copy of the browser running - and thsu using session() to pass the value is ok, but session() is global to the ONE user, where as ViewState is per page. So, that's why we transfer to ViewState on page load, since FROM THAT POINT onwards in that page, and code behind, we use ViewState. If we used session() in the code behind, then it is global, and if more then one copy of the browser is running or even multiple tables, they will all have the same session() value.
So, say you click on a house to view or buy?
Well, then they might open another tab - display same GV, and click on a different row. If we use session, you now display two pages - but both have the one and same row PK id value - and if you click buy house, you get the wrong house if your code behind uses session(), but with ViewState, the issue does not exist.
And thus, you can even dump your ugle "id" and parameters out of the URL - they look much nicer, but are also much more secure, and the user thus does not have to see, or know about things such as database row PK junk and stuff.

Select Gridview Row - Send to next page

I'm new to this area of programming (ASP.NET VB) and i'm wondering if anyone has a kick start for me so that I can get things moving on my end which I would greatly appreciate! I'm currently using code to select an entire row (PatientName & Room ) in a Gridview without a "select" button (Below). I would then like to pass these from the row to the next page. The receiving page would have the two in labels. This is where i'm lost.
I know there are examples out there but i can not find an example that fits my case unless someone can point me in the right direction. Thank you
Private Sub GridView1_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
'Allows you to "select"/Highlight a row without a select button
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes("onmouseover") = "this.style.cursor='pointer';this.style.backgroundColor = '#87CEFF';"
e.Row.Attributes("onmouseout") = "this.style.textDecoration='none';this.style.backgroundColor = '#FFFFFF';"
e.Row.ToolTip = "Click to select row"
e.Row.Attributes("onclick") = Me.Page.ClientScript.GetPostBackClientHyperlink(Me.GridView1, "Select$" & e.Row.RowIndex)
End If
End Sub
I would highly suggest including a Select button. The Select Event that it fires would give you all the information you need to find the data you want to display on the next page.
As for the passing of the data, QueryString is the best. Session would be my second choice if you don't want to have it available in the URL (and don't want to encrypt or otherwise obfuscate it).
You can accomplish this in a couple of ways. This is just one way of getting what you need. Say you have the following Data structure.
Public Class Patient
Private patient_Id As Integer
Public ReadOnly Property PatientID As Integer
Get
Return patient_Id
End Get
End Property
Public Property PatientName As String
Public Property Room As Integer
Public Sub New(_patientId As Integer, ByVal _PatientName As String, ByVal _Room As Integer)
patient_Id = _patientId
PatientName = _PatientName
Room = _Room
End Sub
End Class
We need a PatientID to easily find a Patient from a list, an array, etc. In your GridView you can add a HiddenField with the ID of your patients, like this:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="Patient Name">
<ItemTemplate>
<asp:HiddenField runat="server" ID="hiddenPatientID" Value='<%# Eval("PatientID")%>' />
<asp:Label ID="lblPatientName" runat="server" Text='<%# Eval("PatientName")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Room">
<ItemTemplate>
<asp:Label ID="lblPatientRoom" runat="server" Text='<%# Eval("Room")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
That will make the ID of your patient available for your use. You may also access the other information from your patien (PatientName, PatientRoom), I am using PatientID for the sake of this example. The way you access this data from code behind, is by implemmenting the RowDataBound event of your GridView control, like this:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim selectedPatient As Integer = -16
selectedPatient = DirectCast(e.Row.Cells(0).FindControl("hiddenPatientID"), HiddenField).Value
If selectedPatient > 0 Then
e.Row.Attributes("onclick") = Response.Redirect("~/MyOtherPage.aspx?&PatientID=" & selectedPatient)
End If
End If
End Sub
Simple, by using the row's FindControl function, you can access the HiddenField's data, which is in this case your patient's id. You can use this ID in the next page to get to the patient (getPatientById method?) or you could just use the patient's data directly.

Why won't my UpdatePanel update my Listbox as I expect on button click?

I have a form with a dropdownlist, two buttons, and two Listboxes inside an UpdatePanel. The Dropdownlist, and listboxes are all bound to SqlDatasources. The dropdownlist allows you to choose your department.
The first listbox shows a list of Jobs associated with what you've selected from the department.
The second listbox shows an inverse list of those items. (Jobs in the database that are not associated with your department)
When an item is removed from the 1st listbox, it should show up in the 2nd listbox. When an item is removed from the 2nd listbox, it should show up in the 1st listbox.
This functionality allows you to add and remove jobs from your department
The are two buttons on the page function as Add and Remove buttons. Everything is working except the Listboxes will not reliably update. The Data itself is updated in the database, and if I refresh (F5) it will show correctly.
<asp:ScriptManager ID="smgrDeptsJobs" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="uPanelDeptsJobs" runat="server">
<ContentTemplate>
<asp:DropDownList ID="ddlDepartments" runat="server"
DataSourceID="sqldsDepartments" DataTextField="Department"
DataValueField="DeptID" Width="150px" AutoPostBack="True">
</asp:DropDownList>
<asp:ListBox ID="lstJobsIn" runat="server" DataSourceID="sqldsJobsIn"
DataTextField="JobName" DataValueField="JobID" height="156px"
width="220px">
</asp:ListBox>
<asp:Button ID="btnAddJob" runat="server" Text="<<" Width="70px"
CausesValidation="False" />
<asp:Button ID="btnRemoveJob" runat="server" Text=">>" Width="70px"
CausesValidation="False" />
<asp:ListBox ID="lstJobsOut" runat="server" DataSourceID="sqldsJobsOut"
DataTextField="JobName" DataValueField="JobID" height="156px"
width="220px">
</asp:ListBox>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlDepartments"
EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger ControlID="btnAddJob" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="btnRemoveJob" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
The code for the two button click events is below:
Protected Sub btnAddJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddJob.Click
Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
Dim sqlCmdInsert As SqlCommand = sqlJobsDB.CreateCommand()
sqlJobsDB.Open()
sqlCmdInsert.CommandText = _
"INSERT INTO tblDeptsJobs (DeptID, JobID) VALUES " + _
"(#DeptID, #JobID)"
' Declare the data types for the parameters
sqlCmdInsert.Parameters.Add("#DeptID", SqlDbType.TinyInt)
sqlCmdInsert.Parameters.Add("#JobID", SqlDbType.TinyInt)
' Assign the parameters values from the form
sqlCmdInsert.Parameters("#DeptID").Value = ddlDepartments.SelectedValue
sqlCmdInsert.Parameters("#JobID").Value = lstJobsOut.SelectedValue
' Execute the insert Statement
sqlCmdInsert.ExecuteNonQuery()
sqlJobsDB.Close()
End Sub
Protected Sub btnRemoveJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRemoveJob.Click
Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
Dim sqlCmdDelete As SqlCommand = sqlJobsDB.CreateCommand()
sqlJobsDB.Open()
sqlCmdDelete.CommandText = _
"DELETE FROM tblDeptsJobs WHERE tblDeptsJobs.DeptID = #DeptID AND tblDeptsJobs.JobID = #JobID"
' Declare the data types for the parameters
sqlCmdDelete.Parameters.Add("#DeptID", SqlDbType.TinyInt)
sqlCmdDelete.Parameters.Add("#JobID", SqlDbType.TinyInt)
' Assign the parameters values from the form
sqlCmdDelete.Parameters("#DeptID").Value = ddlDepartments.SelectedValue
sqlCmdDelete.Parameters("#JobID").Value = lstJobsIn.SelectedValue
' Execute the insert Statement
sqlCmdDelete.ExecuteNonQuery()
sqlJobsDB.Close()
End Sub
It feels like when I add or remove a job, the listbox that I last selected an item in, is the one that doesn't update.
I also can't get the dropdownlist to update the listboxes without setting autopostback on the dropdownlist to True.
The ugly Band-Aid fix I've come up with is using the listbox.items.clear() method and then rebinding the data for each listbox.
Basically what is happening is that you update your database but never rebind your controls. I'm not sure exactly what you will have to put into your click handlers to make this work (because I have never used the SQL datasource controls before), but it should look something like this:
Protected Sub btnAddJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddJob.Click
Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
Dim sqlCmdInsert As SqlCommand = sqlJobsDB.CreateCommand()
sqlJobsDB.Open()
sqlCmdInsert.CommandText = _
"INSERT INTO tblDeptsJobs (DeptID, JobID) VALUES " + _
"(#DeptID, #JobID)"
' Declare the data types for the parameters
sqlCmdInsert.Parameters.Add("#DeptID", SqlDbType.TinyInt)
sqlCmdInsert.Parameters.Add("#JobID", SqlDbType.TinyInt)
' Assign the parameters values from the form
sqlCmdInsert.Parameters("#DeptID").Value = ddlDepartments.SelectedValue
sqlCmdInsert.Parameters("#JobID").Value = lstJobsOut.SelectedValue
' Execute the insert Statement
sqlCmdInsert.ExecuteNonQuery()
sqlJobsDB.Close()
//may need to do explicit call to DB to get data here
//after you have the data, rebind
lstJobsIn.DataBind();
lstJobsOut.DataBind();
End Sub
That's roughly what it will look like. I would be interested to see what exactly you do to solve your problem.
Just set dropdownlist autopostback to true, remove all triggers and set ChildrenAsTriggers="true" on the updatepanel.

ASP.NET Setting parameter for SqlDataSource programatically does not work for postback

I want to set a parameter for a SqlDataSource programmatically as described in Step 5 at http://www.asp.net/data-access/tutorials/using-parameterized-queries-with-the-sqldatasource-vb . Also a GridView is bound to the sqlDataSource. My markup is:
<asp:SqlDataSource ID="mySqlDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionStringHTL %>"
SelectCommand="SELECT [subscription_con] FROM [HTL_CONSUME_CON] WHERE ([subscription_con] = #subscription_con)">
<SelectParameters>
<asp:Parameter Name="subscription_con" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="myGridView" runat="server" AllowPaging="True"
AllowSorting="True" DataSourceID="mySqlDataSource">
</asp:GridView>
In the codebehind, I have:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
mySqlDataSource.SelectParameters("subscription_con").DefaultValue = calcResult()
End Sub
The return value from calcResult() is different for each postback. The postback occurs when the user clicks a Button on the form that has UseSubmitBehavior=True.
I've use the debugger to step through the code behind and I see it executed for each page load and I see the expected values returned from clacResult().
However the bound DataGrid is never updated on the postbacks, it only updates on the first page load.
If I change the SqlDataSource parameter to have a control as the source, then it works on postbacks. In otherwords, I changed the markup to use:
<asp:ControlParameter ControlID="myTextBox" Name="subscription_con" PropertyName="Text" Type="Int32" />
and I changed the code behind to be:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
myTextBox.Text = calcResult()
End Sub
With the TextBox control as the source of the SqlDataSource parameter, update of the GridView works for the original page load and all postbacks. However, I really have no need for the TextBox and would prefer not to use it.
What am I missing about how to set a parameter programmatically for an SqlDataSource? Why doesn't the bound GridView get updated on postbacks when setting the SqlDataSource parameter programmatically when there is no control source?
You may need an explict databaind on postbacks:
if (Page.IsPostBack)
{
grid.DataBind();
}
Should do it.
C#
SqlDataSource1.SelectParameters["Where_Clause"] = new Parameter() { Name = "Where_Clause", DefaultValue = "WHERE m.Id = 1" };
Greedy Networks.

Resources