Report error, value cannot be null - asp.net

I am stymied by the above error.
I have a report with a parameter called loc.
The intended purpose of the report is to allow users to select a location from the dropdownlist and then records associated with that location are displayed to the users.
The dropdownlist is getting populated with values just fine.
However, when I select a location from the dropdownlist, I get an error that says:
Value cannot be null. Parameter name: reportParameters
Everything works fine when I pass a value as textbox but not as dropdown.
Any ideas what I am doing wrong?
Below are relevant code. Please forgive me in advance for posting a lot of code.
'---Dropdownlist control
<asp:Panel runat="server" ID="pnlLoc" Font-Names="Calibri" BorderStyle="Solid" BorderWidth="1" Style="margin: 0 auto; width:300px;">
<table>
<tr>
<td>
<asp:Label runat="server" ID="lblLoc" Text="Location: " />
</td>
<td>
<asp:DropDownList runat="server" ID="ddLoc" DataSourceID="dslocator6" AutoPostBack="True">
</asp:DropDownList>
</td>
</tr>
</table>
</asp:Panel
--Report viewer control
<rsweb:ReportViewer ID="ReportViewer1" runat="server" AsyncRendering="true" SizeToReportContent="true" Font-Names="Arial"
Height="675px" Width="750px">
<LocalReport EnableExternalImages="true" ReportPath="">
</LocalReport>
</rsweb:ReportViewer></center>
<asp:ObjectDataSource ID="LOC" runat="server" SelectMethod="GetData" TypeName="ManageReportsTableAdapters.searchBylocationsTableAdapter">
<SelectParameters>
<asp:ControlParameter ControlID="ddLoc" Name="Location" DefaultValue=" " />
</SelectParameters>
</asp:ObjectDataSource>
--This code populates the ddLoc dropdownlist
Protected Sub btnLoc_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLoc.Click
ReportViewer1.LocalReport.ReportPath = ""
pnlLoc.Visible = True
which.Value = "P"
dslocator6.SelectCommand = "SELECT location FROM Locations ORDER BY [location]"
ddLoc.DataTextField = "location"
ddLoc.DataValueField = "location"
End Sub
'Define report parameter
Dim params(0) As ReportParameter
ReportViewer1.LocalReport.DataSources.Add(New ReportDataSource("locs", LOC.ID))
ReportViewer1.LocalReport.ReportPath = "locations.rdlc"
ReportViewer1.LocalReport.Refresh()
If Not String.IsNullOrEmpty(ddLoc.SelectedValue) Then
params(0) = New ReportParameter("loc", ddLoc.SelectedValue)
Else
params(0) = New ReportParameter("loc", sel, False)
End If
ReportViewer1.LocalReport.SetParameters(params) '<-- error points to this line

I was getting this error and the problem was me setting an extra index in my array
Dim params(2) As ReportParameter
params(0) = New ReportParameter("SignatureImg", "SomeBase64StringHere")
params(1) = New ReportParameter("SignatureImgMimeType", "image/png")
ReportViewer1.LocalReport.SetParameters(params)
Because of I defined my array like this Dim params(2) As ReportParameter and i was just adding values for the first two index the value on index 3 was null and it was creating the problem.
The solution was just defined the array like this Dim params(1) As ReportParameter.

Related

Formview cascading dropdown issue

I'm working on a Formview where in the EditTemplate, I have 1 dropdownlist dependent on another dropdownlist value.
I've looked at some examples and have found this one to be the most concise and I am working off of it:
http://mikepope.com/blog/AddComment.aspx?blogid=1629
It's pretty straight-forward but it's not working for my ddl. Can you tell me what I am missing or not implementing properly? I have removed some of the code in order to troubleshoot but still, nothing. For example, I am not setting the selectedValue as nothing is being returned...
Any advice would be appreciated.
Thanks
HTML:
<EditItemTemplate>
...
...
...
<tr>
<td colspan="6" align="left">
<asp:DropDownList ID="ddTeams" runat="server" CssClass="myDropDownIndent" DataSourceID="sqlGetTeams" DataTextField="Team" DataValueField="Team" SelectedValue='<%# DetermineTeamValue(Eval("Team")) %>' AutoPostBack="true" OnSelectedIndexChanged="DropDownList_SelectedIndexChanged">
</asp:DropDownList>
</td>
<td colspan="4" align="left">
<asp:DropDownList ID="DropDownOwner" runat="server" CssClass="myDropDown" DataSourceID="sqlGetMembers2" DataTextField="EmployeeName" DataValueField="EmployeeName" OnSelectedIndexChanged="DropDownList_SelectedIndexChanged">
</asp:DropDownList>
<asp:SqlDataSource ID="sqlGetMembers2" runat="server" ConnectionString="<%$ ConnectionStrings:ProjectDashboardConnectionString %>"
SelectCommand="usp_GetMembers" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="Type" />
<asp:Parameter Name="TeamID" />
</SelectParameters>
</asp:SqlDataSource>
</td>
</tr>
Code Behind:
Protected Sub fvTask_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles fvTask.DataBound
If fvTask.CurrentMode = FormViewMode.Edit Then
Dim dv As System.Data.DataRowView = fvTask.DataItem
Dim ddTeams2 As DropDownList = fvTask.FindControl("ddTeams")
Dim DropDownOwner As DropDownList = fvTask.FindControl("DropDownOwner")
Dim a As String = "A"
Dim dsc As SqlDataSource = fvTask.FindControl("sqlGetMembers2")
dsc.SelectParameters("TeamID").DefaultValue = String.Empty
dsc.SelectParameters("Type").DefaultValue = String.Empty
DropDownOwner.DataBind()
'If Not IsDBNull(dv("EmployeeName")) Then
' DropDownOwner.SelectedValue = dv("EmployeeName")
'End If
End If
Catch ex As Exception
ErrMessage = ex.ToString
End Try
End Sub
So, my 2nd dropdownlist is null.

how to fill listview cell with value from detailsview

I would like to know if is it possible to retrieve the value from a ddlist (Id) and assign it to a cell/ textbox of a listview?
I have 3 controls, ddl, detailsview, and listview on the web page.
The ddl controls the record that is displayed on the detailsview and the listview.
I would like to have the Recipe Id in the listview, to the id of the record selected in the ddl or the record id of the detailsview.
The 3 controls use entitydatasource to get the data.
Thank you greatly.
some code I tried without success was to have a sub running on the databound of the listview:
Protected Sub lvRecipeSteps_ItemDataBound(sender As Object, e As ListViewItemEventArgs) Handles lvRecipeSteps.DataBound
If e.Item.ItemType = ListViewItemType.DataItem Then
Dim dataItem As ListViewDataItem = DirectCast(e.Item, ListViewDataItem)
If dataItem.DisplayIndex = lvRecipeSteps.EditIndex Then
Dim tb__1 As TextBox = TryCast(e.Item.FindControl("Recipe_IdTextBox"), TextBox)
End If
End If
End Sub
I get this error:
Unable to cast object of type 'System.EventArgs' to type 'System.Web.UI.WebControls.ListViewItemEventArgs'
===========================================
This is the entitydatasource that the listview uses:
<asp:EntityDataSource
ID="EntityDataSource_RecipeSteps"
runat="server"
ConnectionString="name=OLTPEntities"
DefaultContainerName="OLTPEntities"
EnableFlattening="False"
EntitySetName="RefineRecipeStep"
Where="it.Recipe_Id = #RecipeID"
EnableDelete="True"
EnableInsert="True"
EnableUpdate="True"
EntityTypeFilter="RefineRecipeStep"
OrderBy="it.ProcessType, it.AdditionOrder">
<WhereParameters>
<asp:ControlParameter ControlID="ddRecipeItemNumber" DbType="Int32" Name="RecipeID" PropertyName="SelectedValue" />
</WhereParameters>
This is the field I am trying to have filled with the Id from the ddl, or detailsview:
<td class="RefineRecipe_Steps_Cells">
<asp:TextBox
ID="Recipe_IdTextBox"
runat="server"
Text='<%# Bind("Recipe_Id") %>' />
<asp:CustomValidator
ID="CustomValidator_Recipe_Id"
runat="server"
ErrorMessage="Enter numbers only, please"
ControlToValidate="Recipe_IdTextBox"
OnServerValidate="ServerValidation_IsNumber"
CssClass="cssCustomValidator"
Display="Dynamic">Digits only, please</asp:CustomValidator>
<asp:RequiredFieldValidator
ID="ReqField_RecipeId"
runat="server"
ErrorMessage="* Required"
ControlToValidate="Recipe_IdTextBox"
CssClass="cssCustomValidator"
Display="Dynamic">* Required</asp:RequiredFieldValidator>
</td>
Please any advice on how to do this would be much appreciated.
Thank you very much.

Object reference not set to an instance of an object. - Visual Basic (Web)

So, I'm having a slight problem with my code.
I was working on a small school project (recreation of book library) and encountered a problem which I cannot get a grasp of.
So, the user can search for a list of books, and after the list is populated (via DataList control), a small button "Book now" (Reserve) appears which user can click and reserve his book.
This is the code for the DataList control that resides in "Search.aspx"
<asp:DataList ID="DataList1" runat="server" DataKeyField="knjigaId" DataSourceID="SearchSqlDataSource" CssClass="searchControl">
<ItemTemplate>
<div class="pictureOfFoundBook">
<asp:Image ID="pictureOfFoundBook_imageLink" runat="server" ImageUrl='<%#"~/GetImage.aspx?knjigaId=" & Eval("knjigaId") & "&img=naslovnica" %>' />
</div>
<div class="descriptionOfFoundBook">
Naziv: <asp:Label ID="Label1" runat="server" Text='<%# Eval("naziv") %>' /><br />
Godina izdanja: <asp:Label ID="Label2" runat="server" Text='<%# Eval("godinaIzdanja") %>' /><br />
Broj stranica : <asp:Label ID="brojStranicaLabel" runat="server" Text='<%# Eval("brojStranica") %>' /><br />
Izdavač: <asp:Label ID="NazivIzdavacaLabel" runat="server" Text='<%# Eval("NazivIzdavaca") %>' /><br />
Vrsta tiskovine : <asp:Label ID="NazivVrsteTiskovineLabel" runat="server" Text='<%# Eval("NazivVrsteTiskovine") %>' /><br />
Kategorija: <asp:Label ID="NazivKategorijeLabel" runat="server" Text='<%# Eval("NazivKategorije") %>' /><br /><br />
<asp:HyperLink ID="foundBookEditHL_adminOnly" runat="server" NavigateUrl='<%# "~/admin/knjigeEdit.aspx?knjigaId=" & Eval("knjigaId") %>'>Uredi knjigu</asp:HyperLink><br />
<asp:Button ID="rezervacijeButton" runat="server" Text="Rezerviraj" OnClick="rezervacijaClick" CommandArgument='<%# Eval("knjigaId") %>'/><br />
<asp:Label ID="rezStatusLabel" runat="server"></asp:Label>
<asp:PlaceHolder ID="rezStatusPlaceholder" runat="server"></asp:PlaceHolder>
</div>
<hr />
</ItemTemplate>
</asp:DataList>
I've set the DataList1 control as a Friend sub so I can access the controls in it from another sub;
Friend Sub DataList1_ItemCreated(sender As Object, e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemCreated
End Sub
I was trying to do the following; on the click of a button "rezervacijeButton", a function "rezervacijaClick" runs, which populates the table in the database.
Protected Sub rezervacijaClick(sender As Object, e As System.EventArgs)
Dim Conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("LocalSqlServer").ToString)
Dim cmd As New System.Data.SqlClient.SqlCommand
Dim sql As New StringBuilder
Dim rezstatus As Label = DataList1.FindControl("rezStatusLabel")
sql.Append("INSERT INTO rezervacije(UserName, knjigaId) VALUES (#UserName, #knjigaId)")
Dim buttonsender As Button = sender
cmd.Parameters.AddWithValue("UserName", User.Identity.Name)
cmd.Parameters.AddWithValue("knjigaId", buttonsender.CommandArgument)
Conn.Open()
cmd.CommandText = sql.ToString
cmd.Connection = Conn
cmd.ExecuteNonQuery()
Conn.Close()
buttonsender.Visible = False
rezstatus.Text = "aaa"
'Try
' rezstatus.Text = "testing..."
'Catch ex As Exception
' exlabel.Text = "POGREŠKA"
' exlabel.ForeColor = Drawing.Color.Red
'End
End Sub
The next thing I wanted to do in the function "rezervacijaClick" was to set the text value of the Label (with ID "rezStatusLabel", which resides inside the DataList1 control) to "SOME TEXT" after the "Reserve" button is clicked.
But after the button click, I get the following error :
Object reference not set to an instance of an object.
Line 21:
Line 22: buttonsender.Visible = False
Line 23: rezstatus.Text = "aaa"
Line 24:
Line 25: 'Try
Your rezstatus object is Nothing (null).
This is happening because you aren't looking in the right place for your label.
Each record of data you bind to the DataList will create a new hierarchy of controls, containers that hold the other controls you have defined in your ItemTemplate.
The immediate descendants of DataList1 will be a collection of DataListItem objects and then you will have your controls inside those.
Since we don't know for sure (unless you know you are only binding one record to the DataList) which DataListItem the desired label will be in, we simply walk backwards up the control tree and find the label from there.
Because you are responding to a button click event in your rezervacijaClick method, the parameter sender will be of type Button and will come from rezervacijeButton, so we can use that information to find your label:
Dim clickedButton As Button = CType(sender, Button) 'convert the sender parameter to the correct type: Button
Dim buttonParent As Control = clickedButton.Parent 'get a reference to the button's parent control
Dim rezstatus As Label = CType(buttonParent.FindControl(""), Label) 'find the label by ID and convert it to a Label as the return type of FindControl is Control
I would recommend that, instead of using the Button click event, you use the DataList.ItemCommand event. It will make your life a lot easier. This event fires whenever a Button is clicked within a row of your DataList control.
This way, you get the index passed in through the DataListCommandEventArgs parameter. then you would just need to update your DataList markup to add the event handler:
<asp:DataList ID="DataList1" runat="server" DataKeyField="knjigaId"
DataSourceID="SearchSqlDataSource" CssClass="searchControl"
ItemCommand="DataList1_ItemCommand" >
And your handler code would look like this:
Protected Sub DataList1_ItemCommand(sender As Object, e As System.EventArgs)
Dim Conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("LocalSqlServer").ToString)
Dim cmd As New System.Data.SqlClient.SqlCommand
Dim sql As New StringBuilder
Dim rezstatus As Label = e.Item.FindControl("rezStatusLabel")
sql.Append("INSERT INTO rezervacije(UserName, knjigaId) VALUES (#UserName, #knjigaId)")
Dim buttonsender As Button = e.Item.FindControl("rezervacijeButton")
cmd.Parameters.AddWithValue("UserName", User.Identity.Name)
cmd.Parameters.AddWithValue("knjigaId", buttonsender.CommandArgument)
Conn.Open()
cmd.CommandText = sql.ToString
cmd.Connection = Conn
cmd.ExecuteNonQuery()
Conn.Close()
buttonsender.Visible = False
rezstatus.Text = "aaa"
End Sub

Change textbox value when selecting dropdownlist value

I have a dropdownlist control that shows the primary key from a table called model, and a textbox that should show another value(a foreign key) from that same table when I use the dropdownlist.
Both PK and FK have a single value.
Since I didn't have a clue how to do this, I used a search method that should be called everytime someone selects a new value from the dropdownlist.
Search code:
Public Function searchArea(ByVal model As String) As String
Dim mycon As New Connection
Using connection As New SqlConnection(mycon.GetConnectionString())
Using command As New SqlCommand()
command.Connection = connection
command.CommandType = CommandType.Text
command.CommandText = "SELECT area FROM model WHERE model= #model"
command.Parameters.AddWithValue("#model", model)
connection.Open()
Dim dataReader As SqlDataReader = command.ExecuteReader()
If (dataReader.Read()) Then
Return dataReader.ToString(0)'this query should always have a single value
End If
Return "Nothing"
End Using
End Using
End Function
Event code:
Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles DropDownList1.SelectedIndexChanged
Dim objModel As New ModelDAO 'the class where the method is
TextBox9.Text = objModel.searchArea(DropDownList1.Text)
End Sub
.
<asp:DropDownList ID="DropDownList1" runat="server" AppendDataBoundItems="True"
DataSourceID="SqlDataSource1" DataTextField="MODEL" DataValueField="MODEL">
<asp:ListItem Text="-Select-" Value="" />
</asp:DropDownList>
<asp:TextBox ID="TextBox9" runat="server" Enabled="False" Height="24px"
Width="219px"></asp:TextBox>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:DBUserInterfaceConnectionString %>"
SelectCommand="SELECT [MODEL] FROM [MODEL]">
</asp:SqlDataSource>
But as I thought, it doesn't work, can you help me please?
EDIT: Thanks, now it triggers, but I'm getting the value: 'S' that value doesn't belong to my table.Can you tell me if my search method is ok?
Try to add this
<asp:DropDownList ID="DropDownList1"
runat="server"
AutoPostBack="true"
OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
.....
</asp:DropDownList>
Try to Load datareader into datatable and than use it to print data into the textbox..
Thank you everyone, I solved it with this:
Return dataReader.GetString(0)
instead of:
Return dataReader.ToString(0)
It was just a type conversion problem.

Double Databinding Cascading DropDownList to two SqlDataSources in a FormView

I have two cascading dropdown lists I'm attempting to bind to two separate SqlDataSources each.
These dropdownlists exist in a FormView's EditItemTemplate. Inside the EditItemTemplate two sqldatasource controls exist that populate the department and the jobname. The DeptID and the JobID are the primary keys in those tables. This creates the "cascading effect" between departments and jobs. When a department is selected, only the jobs associated with that department appear.
This piece is working properly.
<asp:FormView ID="frmProfile" runat="server" DataSourceID="sqlDSProfile"
DataKeyNames="EUID" style="margin-top: 0px">
<EditItemTemplate>
<asp:DropDownList ID="ddlDepartments" runat="server" Width="135px"
DataSourceID="sqlDSDepartments"
DataTextField="Department"
DataValueField="DeptID" AutoPostBack="True"
SelectedValue='<%# Bind("CurrentDeptID") %>'
AppendDataBoundItems="true" >
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlJobNames" runat="server" Width="185px"
DataSourceID="sqlDSJobs" DataTextField="JobName" DataValueField="JobID"
SelectedValue='<%# Bind("CurrentJobID") %>'
AppendDataBoundItems="true" >
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="sqlDSDepartments" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblDepartments.DeptID,
tblDepartments.Department
FROM tblDepartments" />
<asp:SqlDataSource ID="sqlDSJobs" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblJobs.JobID, tblJobs.JobName FROM tblJobs
INNER JOIN tblDeptsJobs ON tblDeptsJobs.JobID = tblJobs.JobID
WHERE tblDeptsJobs.DeptID = #DeptID" >
<SelectParameters>
<asp:ControlParameter ControlID="ddlDepartments" Name="DeptID"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
</asp:FormView>
Outside the formview the SqlDataSource exists that binds all of the information to the Employee table in an update statement. I'm leaving all of the other information in this SqlDataSource even though it's been omitted from the FormView above.
<asp:SqlDataSource ID="sqlDSProfile" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblEmployee.EUID,
tblEmployee.DateHired,
tblEmployee.LastName,
tblEmployee.HiredLastName,
tblEmployee.FirstName,
tblEmployee.Role,
tblEmployee.JobGrade,
tblEmployee.CurrentDeptID,
tblDepartments.Department,
tblDepartments.DeptID,
tblEmployee.CurrentJobID,
tblJobs.JobName,
tblJobs.JobID,
tblEmployee.CurrentShift,
tblEmployee.JobDate,
tblEmployee.IsDisplaced,
tblEmployee.EligibilityDate
FROM tblEmployee
LEFT OUTER JOIN tblDepartments ON tblEmployee.CurrentDeptID = tblDepartments.DeptID
EFT OUTER JOIN tblJobs ON tblEmployee.CurrentJobID = tblJobs.JobID
WHERE (tblEmployee.EUID = #EUID)"
UpdateCommand="UPDATE [tblEmployee]
SET [tblEmployee].[DateHired] = #DateHired,
[tblEmployee].[LastName] = #LastName,
[tblEmployee].[HiredLastName] = #HiredLastName,
[tblEmployee].[FirstName] = #FirstName,
[tblEmployee].[Role] = #Role,
[tblEmployee].[JobGrade] = #JobGrade,
[tblEmployee].[CurrentDeptID] = #CurrentDeptID,
[tblEmployee].[CurrentJobID] = #CurrentJobID,
[tblEmployee].[CurrentShift] = #CurrentShift,
[tblEmployee].[JobDate] = #JobDate,
[tblEmployee].[IsDisplaced] = #IsDisplaced,
[tblEmployee].[EligibilityDate] = #EligibilityDate
WHERE [tblEmployee].[EUID] = #EUID"
ProviderName="System.Data.SqlClient">
<SelectParameters>
<asp:SessionParameter Name="EUID" SessionField="sProfileEUID" DbType="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="DateHired" DbType="Date" />
<asp:Parameter Name="LastName" DbType="String" />
<asp:Parameter Name="HiredLastName" DbType="String" />
<asp:Parameter Name="FirstName" DbType="String" />
<asp:Parameter Name="Role" DbType="String" />
<asp:Parameter Name="JobGrade" DbType="Byte" />
<asp:Parameter Name="CurrentDeptID" DbType="Int32" />
<asp:Parameter Name="CurrentJobID" DbType="Int32" />
<asp:Parameter Name="CurrentShift" DbType="Int32" />
<asp:Parameter Name="JobDate" DbType="Date" />
<asp:Parameter Name="IsDisplaced" DbType="Boolean"/>
<asp:Parameter Name="EligibilityDate" DbType="Date"/>
<asp:SessionParameter Name="EUID" SessionField="sProfileEUID" DbType="String" />
</UpdateParameters>
</asp:SqlDataSource>
The only pieces I can't figure out how to bind are the Departments and the Jobs. Everything else is working. I've tried using the following code in the DropDownList controls...
SelectedValue='<%# Bind("CurrentDeptID") %>'
SelectedValue='<%# Bind("CurrentJobID") %>'
...but these result in errors.
Summary
When the user clicks edit, I need the values in the two dropdownboxes to pull their selectedvalue from the main sqlDSProfile data source, but I need them to be updatable. I've gotten it to the point where I can update and bind the job that an associate belongs to, but because the dropdownlists cascade, when I attempt to change the department the AutoPostBack breaks the binding between sqlDSProfile - CurrentJobID and ddlJobs.
Update
I added tblEmployee.CurrentDeptID and tblEmployee.CurrentJobID to the select statement, and added Bind() statements to the DropDownList controls.
SelectedValue='<%# Bind("CurrentDeptID") %>'
SelectedValue='<%# Bind("CurrentJobID") %>'
The two DropDownLists are now populated with accurate information pulled from the Employee table, showing the department and job that the employee belongs to.
The two DropDownLists are also populated by the two SqlDataSources inside the FormView, giving me options for changing the department and changing the job.
When I change the Job, it works and the employees job is updated.
When I change the Department, it breaks saying DataBinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
Close to Done
I removed the data binding from ddlJobs and coded that in the background.
Protected Sub frmProfile_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles frmProfile.ItemUpdating
If frmProfile.CurrentMode = FormViewMode.Edit Then
e.NewValues("CurrentJobID") = DirectCast(DirectCast(sender, FormView).FindControl("ddlJobs"), DropDownList).SelectedValue
End If
End Sub
The only piece that's left is building the code for when the ddlDepartments changes.
pseudocode...
' If Item exists in ddlJobs Then
' select item (CurrentJobID)
' else
' select index 0 and make them pick something new
' end if
So Close!
Updated Again
This is the code I've developed to loosely bind this. In the page_load I'm trying to pull the contents of CurrentJobID from sqlDSProfile and check to see if that value exists in ddlJobs. If it does I want to set ddlJobs.SelectedValue = to that CurrentJobID. If it doesn't I want to set the selectedindex to 0 which is a message saying "pick one" or something.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If frmProfile.CurrentMode = FormViewMode.Edit Then
' Need to determine if the CurrentJobID returned in the select statement
' exists in the ddlJobs dropdownlist. If it does, set that to the
' selectedvalue, if not set it to 0 so the user can select a new job.
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
Dim dvProfile As DataView = sqlDSProfile.Select(DataSourceSelectArguments.Empty)
Dim drvProfile As DataRowView = dvProfile(0)
If ddlJobs.Items.FindByValue(drvProfile("CurrentJobID")) Is DBNull.Value Then
ddlJobs.SelectedIndex = 0
Else
ddlJobs.SelectedValue = drvProfile("CurrentJobID")
End If
End If
End Sub
Its returning a null reference exception on the line where I'm checking for dbnull.value
I had a similar issue and found a very simple resolution, (and in c#). Imagine a database with a table Questions, related to category and subcategory tables (which are also related and constrained). When trying to update existing records asp throws an error. This is the solution that I worked out thanks to the information above from Lucretius et al.
Only databind the parent dropdownlist
Find a way to insert the child dropdown selected value on the update event of the datasource.
As:
protected void odseditquestion_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
//dynamically assign value from ddlsubcategory to odseditquestion on updating event
//you really should not have to do this
DropDownList ddlsubcategory = (DropDownList)fveditquestion.FindControl("ddlsubcategory");
e.InputParameters["subcatid"] = (ddlsubcategory.SelectedValue);
}
It works on my application. Hope it helps somebody, this one cost me half a day, such is asp!!
The problem can be if tlbEmployee columns in the SqlDSProfile in the update statement and field names used by your controls do not match. Other procedures you've followed are right.
SqlDataSource control expects field names it updates to be similar
with those bound to the controls(fields) inside the DataBound control.
The Solution can be: change all the update Parameters to ControlParameters referencing the right control for each one
Update: Wait, I think the problem is your select statement of the SqlDSProfile should contain: CurrentDeptID and CurrentJobID. Try it:
<asp:SqlDataSource ID="sqlDSProfile" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblEmployee.EUID,
tblEmployee.DateHired,
tblEmployee.LastName,
tblEmployee.HiredLastName,
tblEmployee.FirstName,
tblEmployee.Role,
tblEmployee.JobGrade,
tblDepartments.Department,
tblJobs.JobName,
tblEmployee.CurrentShift,
tblEmployee.JobDate,
tblEmployee.IsDisplaced,
tblEmployee.EligibilityDate
tblEmployee.CurrentDeptID,
tblEmployee.CurrentJobID
FROM tblEmployee
Advice: Test your code portion by portion.
Try the code without the dropdownlist, Test separately
Add the one drop downlist
Use select * from ... in select queries
Avoid ajax when testing
If you make it
Add portions of code portion after portion
at last use the partial updating (ajax)
I have a working solution now, thanks in part to Nuux and a bunch of online research. The tip about the join statement wasn't relevant, but the tip about including "CurrentJobID" and "CurrentDeptID" in my select query was spot on.
In addition to that I had to rework the controls a little. The two cascading dropdownlists are below. The ddlJobs dropdown list behaves like a normal databound control, but it doesn't have the Bind("CurrentJobID") statement I was trying in my original post.
<asp:DropDownList ID="ddlDepartments" runat="server" Width="185px"
DataSourceID="sqlDSDepartments"
DataTextField="Department"
DataValueField="DeptID"
SelectedValue='<%# Bind("CurrentDeptID") %>'
AppendDataBoundItems="true"
AutoPostBack="True" >
<asp:ListItem Text="--Select One--" Value="" />
</asp:DropDownList>
<asp:DropDownList ID="ddlJobs" runat="server" Width="185px"
DataSourceID="sqlDSJobs"
DataTextField="JobName"
DataValueField="JobID"
AppendDataBoundItems="true"
OnDataBinding="ddlJobs_DataBinding" />
The only thing the custom routine "ddlJobs_DataBinding" is doing is adding "--Select One--" as index 0 in the ddlJobs dropdown. I tried this in several places, like page_load, and the databound event of the formview with no success.
Protected Sub ddlJobs_DataBinding(sender As Object, e As System.EventArgs)
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
Dim liSelectOne As New ListItem("--Select One--", 0)
ddlJobs.Items.Clear()
ddlJobs.Items.Insert(0, liSelectOne)
End Sub
The databound event of the formview frmProfile_DataBound event does do some work though. When the user clicks "edit" on the formview to enter editing mode this ensures that the dropdownlist ddlJobs has the correct job selected by default for the profile in question. If the user hasn't been assigned to a job then it defaults to selectedindex 0 which is "--Select One--" set in custom databinding event just above.
Protected Sub frmProfile_DataBound(sender As Object, e As System.EventArgs) Handles frmProfile.DataBound
If frmProfile.CurrentMode = FormViewMode.Edit Then
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
Dim dvProfile As DataView = sqlDSProfile.Select(DataSourceSelectArguments.Empty)
Dim drProfile As DataRow = dvProfile.Table.Rows(0)
If drProfile("CurrentJobID").ToString() = "" Then
ddlJobs.SelectedIndex = 0
Else
ddlJobs.SelectedValue = drProfile("CurrentJobID").ToString()
End If
End If
End Sub
Finally, if the user selects a new job from ddlJobs, that value has to be fed to the database, which the ItemUpdating event of the formview handles.
Protected Sub frmProfile_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles frmProfile.ItemUpdating
If frmProfile.CurrentMode = FormViewMode.Edit Then
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
e.NewValues("CurrentJobID") = ddlJobs.SelectedValue
End If
End Sub
Done!

Resources