I currently have an XML file where information is saved when text data is submitted. I also have a TextBox and Button for users to search for the information they submitted.
As an example, I want the users to be able to search a registration number, and once they press the search button the result will only display if it is an exact match. I currently have the XML data bound through a GridView, and I am currently using an unfinished if/else statement for the search part, however the data will not display on the client side unless I input the exact data in the if/else statement. What options are there to correct this?
This is the C#
protected void Searchbutton_Click(object sender, EventArgs e)
{
DataSet ds;
string filepath = Server.MapPath("~/App_Data/RegData.xml");
ds = new DataSet();
ds.ReadXml(filepath);
RES.DataSource = ds.Tables[1].DefaultView;
RES.DataBind();
var sr = Searchreg.Text;
var dss = Convert.ToString(ds);
if (sr.Equals("12345678"))
{
RES.DataSource = ds.Tables[1].DefaultView;
}
else
{
none.Visible = true;
RES.Visible = false;
}
}
And this is from the aspx page
<table>
<tr>
<td>
<asp:TextBox runat="server" ID="Searchreg"></asp:TextBox>
</td>
<td>
<asp:Button runat="server" ID="Searchbutton" Text="Search" OnClick="Searchbutton_Click" />
</td>
</tr>
<tr>
<td>
<asp:GridView runat="server" ID="RES" CellPadding="4" AutoGenerateColumns="false">
<Columns>
<asp:BoundField HeaderText="Registration" DataField="Registration" />
</Columns>
</asp:GridView>
</td>
<td>
<asp:Label runat="server" ID="none" Text="No Results" Visible="false"></asp:Label>
</td>
</tr>
</table>
This is an example from the XML file:
<registration>
<own>
<Name>afadf</Name>
<Address>afaf</Address>
<Number>adfad</Number>
<Registration>12345678</Registration>
<BoatLength>adfd</BoatLength>
<ManufacturerYear>adf</ManufacturerYear>
<LeaseStart>16/06/2016</LeaseStart>
<LeaseEnd>24/06/2016</LeaseEnd>
<Cost>Total Cost: $40</Cost>
</own>
<lease></lease>
</registration>
You could supply RowFilter to DataTable
DataView dv = ds.Tables[1].DefaultView;
dv.RowFilter = "registration = " + Searchreg.Text; // use correct column name.
RES.DataSource = = dv;
Related
I use this code to put the selected gridview row to Label or textbox and they are working properly, However when I choose to display the data in a dropdownlist which loads data from sqldatasource, it produces this error:
'ddlRPGroup' has a SelectedValue which is invalid because it does not exist in the list of items.
protected void grdTenant_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = grdTenant.SelectedRow;
lblRPCode.Text = row.Cells[1].Text;
lblRP.Text = row.Cells[2].Text;
lblType.Text = row.Cells[3].Text;
lblBusiness.Text = row.Cells[4].Text;
ddlRPGroup.SelectedValue = row.Cells[5].Text;
}
Markup
<table border="0" class="tblEditTenant" cellpadding="3">
<tr>
<td colspan ="4" style="font-weight: 700; font-size: medium;"><asp:Label ID="lblRP" runat="server" Text="Retail Partner"></asp:Label>-
<asp:Label ID="lblRPCode" runat="server" Text="RP Code"></asp:Label> </td>
</tr>
<tr>
<tr>
<td>Type:</td>
<td colspan ="3"><asp:Label ID="lblType" runat="server" Text="Type"></asp:Label></td>
</tr>
<tr>
<td>Business:</td>
<td colspan ="3"><asp:Label ID="lblBusiness" runat="server" Text="Business"></asp:Label></td>
</tr>
<tr>
<td>RP Group:</td>
<td colspan ="3">
<asp:DropDownList ID="ddlRPGroup" runat="server" DataSourceID="SqlDataSource3" DataTextField="name" DataValueField="code"></asp:DropDownList> <asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</td>
</tr>
</table>
What the error tells you, that the value you want to select in your DropdownList does not yet exist in the list.
If this value already should be in the ddl, then you need to edit the DataSource of your ddl to insert the correct values.
If you want to insert the selected value into the dropdownlist first and then select it, do it like this:
protected void grdTenant_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = grdTenant.SelectedRow;
lblRPCode.Text = row.Cells[1].Text;
lblRP.Text = row.Cells[2].Text;
lblType.Text = row.Cells[3].Text;
lblBusiness.Text = row.Cells[4].Text;
//new ListItem with Text and Value of cells[5] gets inserted into ddl
ddlRPGroup.Items.Insert(0, new ListItem(row.Cells[5].Text,row.Cells[5].Text));
ddlRPGroup.SelectedValue = row.Cells[5].Text;
}
If this value should already be in the list, the you need to edit your datasource to return to proper values.
Found out the answer already, and what is causing the error.
Just replace this line
ddlRPGroup.SelectedValue = row.Cells[5].Text;
with this:
ddlRPGroup.SelectedItem.Text = row.Cells[5].Text;
It should be selectItem.Text because selectedValue points the code of the item and not the item itself
My Requirement is. I will be uploading 3-4 images at a time through FileUpload. Each Image will have its own Title, Descriptions etc.
Now my issue is that, whenever uploading I have given a title column for the images. But when I upload 3-4 Images the title and description is going same for all the images.
Here Is my HTML for the Image Uploading via FileUpload.
<tr>
<td style="vertical-align: top;">
<asp:label cssclass="control-label" id="Label1" runat="server">Image Title</asp:label>
</td>
<td>
<div class="control-group">
<div class="controls">
<asp:textbox id="txtImagetitle" cssclass="form-control" runat="server" validationgroup="AddNew"></asp:textbox>
<asp:requiredfieldvalidator cssclass="error-class" id="RequiredFieldValidator1" runat="server"
controltovalidate="txtImagetitle" errormessage="Please add the image title" validationgroup="AddNew"></asp:requiredfieldvalidator>
</div>
</div>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<asp:label cssclass="control-label" id="Label2" runat="server">Image description</asp:label>
</td>
<td>
<div class="control-group">
<div class="controls">
<asp:textbox id="txtImagedesc" cssclass="form-control" runat="server" validationgroup="AddNew"></asp:textbox>
<asp:requiredfieldvalidator cssclass="error-class" id="RequiredFieldValidator2" runat="server"
controltovalidate="txtImagedesc" errormessage="Please add the image description"
validationgroup="AddNew"></asp:requiredfieldvalidator>
</div>
</div>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<asp:label cssclass="control-label" id="Label3" runat="server">Image upload</asp:label>
</td>
<td>
<div class="control-group">
<div class="controls">
<asp:fileupload id="FileUpload1" runat="server" allowmultiple="true" />
<asp:requiredfieldvalidator cssclass="error-class" id="RequiredFieldValidator3" runat="server"
controltovalidate="FileUpload1" errormessage="Please add the gallery date" validationgroup="AddNew"></asp:requiredfieldvalidator>
</div>
</div>
</td>
</tr>
Please suggest what to do in this case when uploading multiple images how to set different titles for different Images.
UPDATED CODE BEHIND
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (Request.QueryString.Count > 0)
{
foreach (var file in FileUpload1.PostedFiles)
{
string filename = Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath("/GalleryImages/" + filename));
using (SqlConnection conn = new SqlConnection(conString))
if (Request.QueryString["Id"] != null)
{
string Id = Request.QueryString["Id"];
SqlCommand cmd = new SqlCommand();
cmd.CommandText = " Update tbl_galleries_stack SET gallery_id=#gallery_id,img_title=#img_title,img_desc=#img_desc,img_path=#img_path, IsDefault=#IsDefault Where Id=#Id";
cmd.Parameters.AddWithValue("#Id", Id);
cmd.Parameters.AddWithValue("#gallery_id", ddlgallery.SelectedValue);
cmd.Parameters.AddWithValue("#img_title", txtImagetitle.Text);
cmd.Parameters.AddWithValue("#img_desc", txtImagedesc.Text);
cmd.Parameters.AddWithValue("#img_path", filename);
cmd.Parameters.AddWithValue("#IsDefault", chkDefault.Checked);
cmd.Connection = conn;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('Gallery updated sucessfully');window.location ='csrgalleriesstack.aspx';", true);
}
}
}
else
{
foreach (var file in FileUpload1.PostedFiles)
{
string filename = Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath("/GalleryImages/" + filename));
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultCSRConnection"].ConnectionString);
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
SqlCommand cmd1 = new SqlCommand("Insert into tbl_galleries_stack (gallery_id,img_title,img_desc,img_path,IsDefault) values(#gallery_id,#img_title, #img_desc, #img_path,#IsDefault)", conn);
cmd1.Parameters.Add("#gallery_id", SqlDbType.Int).Value = ddlgallery.SelectedValue;
cmd1.Parameters.Add("#img_title", SqlDbType.NVarChar).Value = txtImagetitle.Text;
cmd1.Parameters.Add("#img_desc", SqlDbType.NVarChar).Value = txtImagedesc.Text;
cmd1.Parameters.Add("#img_path", SqlDbType.NVarChar).Value = filename;
cmd1.Parameters.Add("#IsDefault", SqlDbType.Bit).Value = chkDefault.Checked;
cmd1.ExecuteNonQuery();
conn.Close();
ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('Gallery added sucessfully');window.location ='csrgalleriesstack.aspx';", true);
}
}
}
}
There is no way you can give different title / description as you have given no option to provide it. Period.
You are forced to use multiple fileupload controls. This is also tricky because asp:FileUpload controls wont maintain their state after postback.
So, the solution I can see is a two-part one. Create two panels and hide the second panel at page load
Part 1
Place a label and textbox and button like this in the first panel in your page.
When the user enters a value, say 10, and fires EnterButton_click close Panel1 and open Panel2.
Part 2
On Panel 2, place a GridView like this
<asp:GridView ID="ImagesGrid" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Sl No">
<ItemTemplate><%# Container.DisplayIndex + 1 %></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title">
<ItemTemplate>
<asp:TextBox ID="txtTitle" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:TextBox ID="txtDescription" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="File">
<ItemTemplate>
<asp:FileUpload ID="flUpload" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="SaveButton" Text="Save" runat="server" OnClick="SaveButton_Click"/>
Now on the Enter buttons click event on Panel 1, write this.
// the idea is to create an empty gridview with number of rows client selected
protected void EnterButton_Click(object sender, EventArgs e)
{
//in this, 10 has been entered
var imageCount = Convert.ToInt32(txtImageCount.Text);
//var list = new List<string>();
//for (int i = 0; i < imageCount; i++)
//{
// list.Add(string.Empty);
//}
var list = new List<string>(10);
list.AddRange(Enumerable.Repeat(String.Empty, imageCount));
ImagesGrid.DataSource = list;
ImagesGrid.DataBind();
//TO DO: hide panel1 and make panel2 visible
}
So on clicking enter, you will get an empty gridview with ten rows.
Now fill the rows in the GridView, do validation and hit Save. On Save Button click event, you can access the WebControls like this.
protected void SaveButton_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in ImagesGrid.Rows)
{
var title = row.FindControl("txtTitle") as TextBox;
var description = row.FindControl("txtDescription") as TextBox;
var imageFile = row.FindControl("flUpload") as FileUpload;
string filename = Path.GetFileName(imageFile.FileName);
imageFile.SaveAs(Server.MapPath("/GalleryImages/" + filename));
//TO DO: write save routine
}
}
It looks like you only have one set of inputs tied to a single file upload with multiple turned on.
You will either want to turn off multiple and allow the user to add reported sets of those images, or have the editing of title, etc happen in a gridview with the upload.
You could also support a"holding cell " where they upload and then must enter that information before you actually save it to your data store.
I want to visible and invisible my textbox and label from my datalist. My datalist is fulfill with checkboxes. so, i mean i have many checkbox that integrated to database.
I have 2 main data. 1 as the Header and 1 as the subHeader, every subHeader has many checkboxes called access. every access has id_access(i save it into HiddenField 'id_access') and every Header has id_jenis (i save it into HiddenField 'id_jenis_access'). if the access (checkbox text) show 'Others' (id_access = 'ACT5') and the Header show 'Others' (id_jenis = 'JO1') then the label Reaseon and Discribtion with their textbox will show up. but i have problem.
this is my form
<asp:DataList ID="DataListTest" runat="server" OnPreRender="PreTes">
<ItemTemplate>
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<asp:Label ID="lblHeader" runat="server"></asp:Label> <!-- Telephone, Bussines System -->
</td>
</tr>
<tr>
<td>
<asp:Label ID="lblsubheader" runat="server" /></td> <!-- Oracle, EPM, CRM (Muncul di Form) -->
</tr>
<tr>
<td>
<asp:HiddenField ID="id_jenis_access" runat="server" Value='<%Eval(idJenisAccess) %>' /> <!-- Output = JT1, JO1, JBS1 (ID_JENIS) -->
<asp:HiddenField ID="subhd" runat="server" Value='<%# Eval("sub_jenis") %>' /> <!-- Oracle, EPM, CRM (nama sub jenis) -->
<asp:HiddenField ID="id_access" runat="server" Value='<%# Eval("id_access") %>' /><!-- Output = ACT5, ACBS1 -->
<asp:HiddenField ID="hd" runat="server" Value='<%# Eval("nama_jenis") %>' /><!-- Output = Telephone, Bussines System -->
</td>
</tr>
<tr>
<td>
<asp:CheckBox ID="cbCountryName" runat="server" Text='<%# Eval("nama_access") %>' /> <!-- Output = Local, Handphone, Project -->
<asp:TextBox ID="testme" runat="server" Text="" Visible="false" /> <!-- Output = Textbox for all -->
</td>
</tr>
<tr>
<td><asp:Label ID="lblReason" runat="server" Visible="false" text="Reason : "/>
<asp:TextBox ID="txtReason" Text="Reason" runat="server" Visible="false" />
</td>
</tr>
<tr>
<td>
<asp:Label ID="lblDescription" runat="server" Visible="false" text="Description : "/>
<asp:TextBox ID="txtDescription" runat="server" Text="" Visible="false" />
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
this is my code to call all my data from database
private void ShowDataList()
{
conn.Open();
string sql = "Select access.id_access as 'id_access', access.nama_access, jenis_access.id_jenis_access as 'idJenisAccess' , "+
"jenis_access.nama_jenis_access as 'nama_jenis', sub_jenis.nama_sub_jenis as 'sub_jenis',sub_jenis.id_sub_jenis "+
"FROM access LEFT JOIN detil_access ON access.id_access = detil_access.id_access "+
"LEFT JOIN jenis_access ON detil_access.id_jenis_access = jenis_access.id_jenis_access "+
"LEFT JOIN sub_jenis ON detil_access.id_sub_jenis = sub_jenis.id_sub_jenis "+
"ORDER BY jenis_access.id_jenis_access";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataAdapter adp = new SqlDataAdapter(cmd);
dt = new DataTable();
adp.Fill(dt);
DataListTest.DataSource = dt;
DataListTest.DataBind();
}
My problem is my lblReason, txtReason, lblDescribtion, and txtDescription is cannot show.
this is my code on PreRender datalist, i called it PreTes.
protected void PreTes(object sender, EventArgs e)
{
string temp = "";
string subtemp ="";
foreach (DataListItem item in DataListTest.Items)
{
Label objLabel = (Label)item.FindControl("lblHeader");
Label subjenis = (Label)item.FindControl("lblsubheader");
TextBox t = (TextBox)item.FindControl("testme");
CheckBox objName = (CheckBox)item.FindControl("cbCountryName"); // Internet, User Folder, etc (the Access)
HiddenField objHD = (HiddenField)item.FindControl("hd"); // Telephone, Busines System
HiddenField subobjHD = (HiddenField)item.FindControl("subhd"); // Oracle, CRM , EPM
HiddenField id_access = (HiddenField)item.FindControl("id_access"); // ACT5, ACBS1, etc (code Access)
HiddenField id_jenis = (HiddenField)item.FindControl("hdIdJenisAccess"); // JTO1, JBS1, etc (code Jenis)
TextBox tr = (TextBox)item.FindControl("txtReason");
TextBox td = (TextBox)item.FindControl("txtDescription");
Label lblReason = (Label)item.FindControl("lblReason");
Label lblDescription = (Label)item.FindControl("lblDescription");
if (temp != objHD.Value)
{
temp = objHD.Value;
objLabel.Text = temp + "<br/>";
}
if (subtemp != subobjHD.Value)
{
subtemp = subobjHD.Value;
subjenis.Text = subtemp + "<br/>";
}
if (id_access.Value == "ACT5" && id_jenis.Value == "JO1")
{
lblDescription.Visible = true;
td.Visible = true;
lblReason.Visible = true;
tr.Visible = true;
}
}
So, What should I do ?
FYI:i'm a newbie here and also c# programmer
after : HiddenField id_access = (HiddenField)item.FindControl("id_access");
add; var value_id_access = id_access.Text;
some things for other values
I have a table in DB:
NOTICE(NUM,TITLE,CONTENT)
I use Repeater Control in ASP to show all the notices in DB, like:
+----------+------------+|
|title1 (readmore)|
|
|title2 (readmore)|
|
|title3 (readmore)|
......
+------------------------+
All I want is: I read a "title" then I clicked on (readmore), the new page will be opened ( show detail's notice) with the "content" of that notice. How can I assign the num of notice without display it to define the notice in next page?
I just assign the title to property Text of a Label ID="TITLE" because I want to show the title of each notice.
All information I want to show in the this page is: title and the readmore( link to the next page). So that I don't know how to assign the num
My asp page: notice.asp
<asp:Repeater ID="RepDetails" runat="server" >
<HeaderTemplate>
<table style=" width:565px" cellpadding="0" class="borber">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="Title" runat="server" Text='<%#Eval("TITLE") %>' />
</td>
<td>
<asp:HyperLink ID="HyperLink1" runat="server" > (readmord)</asp:HyperLink>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
My C# code:notice.asp.cs
private void BindRepeaterData()
{
string sql = "select num,title from NOTICE";
DataTable ds = l.EXECUTEQUERYSQL(sql);
RepDetails.DataSource = ds;
RepDetails.DataBind();
}
And the next page: detailnotice.asp.cs
private void GetNotice()
{
string sql = "select * from NOTICE where num=" ;// num= the num of notice I choose in notice.asp page.
}
How can I assign a num in Label without display it? What property of Label Control or I should use a other Control ?
Hope you understand what I say. If you don't, please ask?
Basically the same as Sain but using the NavigateURL
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("NUM","~/detailpage.aspx?id={0}") %>' > (readmord)</asp:HyperLink>
hi you can ues anchor tag in place of hyper link button. you can pass num in the query string to the detail page.
<a href='detailpage.aspx?id=<%#Eval("NUM") %>'> (readmord)</a>
On details page you can get query string value and fetch details from database.
int myKey = 0;
if (!string.IsNullOrEmpty(Request.QueryString["id"]))
{
myKey = int.Parse(Request.QueryString["id"]);
// Use myKey to retrieve record from database
}
Ok guys, so I am trying to bind data into a dropdown list from c#. I am getting a Null error when trying to enter the data into the DDL's. I am using this code for the front end.
<asp:Repeater ID="RepeaterHardDrives" runat="server">
<HeaderTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:HiddenField ID="hidHardDrivesPackageDefaultID" runat="server" />
<asp:HiddenField ID="hidHardDrivesPackageDefaultPrice" runat="server" />
<span>
<asp:Label runat="server" ID="lbHardDiskPrice" Text="$00.00/mo"></asp:Label></span><label>Hard
Drive:</label><asp:DropDownList ID="ddHardDrive" DataTextField="ItemName" DataValueField="ProductItemID" runat="server" CssClass="lidropdown">
</asp:DropDownList>
<asp:ImageButton runat="server" ID="ShowHarddriveInfo" ImageUrl="/_Images/server_configurator_helpbutton.png"
OnClick="lnkShowHarddriveInfo_OnClick" /></div>
</td>
<td align="right">
<asp:Label runat="server" ID="lbHardDrivesPrice" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
<br />
</FooterTemplate>
</asp:Repeater>
for the backend I am trying to load a dynamic number of Dropdown lists into the repeater then databind them all with the same data.
public void PopulateHardDrives(int intSupportedDrives)
{
PreloadHardDriveRepeater(intSupportedDrives);
SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["connstrname"].ConnectionString);
SqlCommand cmd = new SqlCommand("Prod_SelectIDNamePriceByCategory", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CategoryCode", "Hard Drive");
DataTable dtHardDrives = new DataTable();
using (conn)
{
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
dtHardDrives.Load(dr);
ViewState.Add("dtHardDrives", dtHardDrives);
}
foreach (RepeaterItem riHardDrive in RepeaterHardDrives.Items)
{
DropDownList ddHardDrives = (DropDownList)riHardDrive.FindControl("ddHardDrives");
ddHardDrives.DataSource = dtHardDrives;//program gives NULL exception error here(object not set to instance of object however it know the count of the rows it is supposed to be pulling)
ddHardDrives.DataValueField = "ProductItemID";
ddHardDrives.DataTextField = "ItemName";
ddHardDrives.DataBind();
Label lbHardDrive = (Label)riHardDrive.FindControl("lbHardDrivesPrice");
lbHardDrive.Text = String.Format("{0:c}", Convert.ToDecimal("0.00"));
if (riHardDrive.ItemIndex != 0) //We do not want to allow None to be selected on the main drive
{
ddHardDrives.Items.Insert(0, "None");
}
}
}
and last but not least the function to setup the dynamic amount of DDL's looks like this
private void PreloadHardDriveRepeater(int intSupportedDrives)
{
int[] intArrDisks = new int[intSupportedDrives];
for (int intDiskCount = 0; intDiskCount < intArrDisks.Length; intDiskCount++)
{
intArrDisks[intDiskCount] = intDiskCount;
}
RepeaterHardDrives.DataSource = intArrDisks;
RepeaterHardDrives.DataBind();
}
I am calling a list of populate functions in a !page.isPostBack if statement and the only one that is not getting the data is this one with the Drown Lists. It gets the number of Rows(18) from the database, but it it throwing a Null error(Object reference not set to an instance of an object.) I have seen quite a few people have been running into this error while googling the problem, however I could not find a solution that worked for me. The PreloadHardDriveRepeater function seems to work fine when run alone it loads the correct amount of DDL's onto the page.
Thanks ahead of time.
Your control is "ddHardDrive":
<asp:DropDownList ID="ddHardDrive" DataTextField="ItemName" DataValueField="ProductItemID" runat="server" CssClass="lidropdown">
and your code is looking for "ddHardDrives"
riHardDrive.FindControl("ddHardDrives");
This would be easy to notice if you debugged into the function and looked at your variable values right before the exception is thrown.