SQL Databinding to Dropdown Lists in Repeaters C# - c#

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.

Related

How to add multi EditItemTemplate in ListView asp.net

as Title
in my code,there are 2 buttons : "btnA" and "btnB"
When I press btnA , I expect that the ListView will show "EditItemTemplate_Edit" and do not show "EditItemTempPlate_Reset"
btnB is similar to btnA
I already added 2 EditItemTemplates in ListView like this :
<EditItemTemplate>
<tr class="EditItemTemplate" style="text-align: left;" id="EditItemTemplate_Eidt">
<td><asp:Label ID="Label_Factory" runat="server" Text='<%# Eval("test1") %>' /></td>
</tr>
<tr class="EditItemTemplate" style="text-align: left;" id="EditItemTemplate_Reset">
<td><asp:Label ID="Label3" runat="server" Text='<%# Eval("test2") %>' /></td>
</tr>
</EditItemTemplate>
I have already tried using script to set "display" -> "none" but it was not work
plz teach me how to make this work
thanks very much ~"~
I actually suggest in these cases to not even bother with the templates.
You can actually use less markup, less code, and less messy UI for the user.
Why not just let them tab around - make as many changes as they want - almost like a Excel sheet.
then have ONE save button - and on un-do button.
That way:
They just edit - not all this song and dance to hit edit + save buttons
So less UI, less code, and you can just tab around on ANY row - just edit.
Much less code.
So, say we have this markup for the listview.
<style> input {border:none}</style>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" >
<ItemTemplate>
<tr style="">
<td><asp:TextBox ID="txtFirst" runat="server" Text='<%# Eval("Firstname") %>' /></td>
<td><asp:TextBox ID="txtLast" runat="server" Text='<%# Eval("LastName") %>' /></td>
<td><asp:TextBox ID="txtCity" runat="server" Text='<%# Eval("City") %>' /></td>
<td><asp:CheckBox ID="Active" runat="server" Checked='<%# Eval("Active") %>' /></td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" border="0" class="table table-hover">
<tr runat="server" style="">
<th runat="server">Firstname</th>
<th runat="server">LastName</th>
<th runat="server">City</th>
<th runat="server">Active</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
<asp:Button ID="cmdSave" runat="server" Text="Save" CssClass="btn-primary" OnClick="cmdSave_Click1" />
<asp:Button ID="cmdAdd" runat="server" Text="Add Row" CssClass="btn-primary" style="margin-left:20px" OnClick="cmdAdd_Click1"/>
<br />
Note how MUCH LESS markup we have.
The code to load this lv looks like this:
private DataTable rstPeople = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadGrid();
ViewState["MyTable"] = rstPeople;
Session["test"] = "hello";
}
else
rstPeople = (DataTable)ViewState["MyTable"];
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from People",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
rstPeople.Load(cmdSQL.ExecuteReader());
ListView1.DataSource = rstPeople;
ListView1.DataBind();
}
}
So we now have this:
So, you are now free to edit - even tab around almost like a Excel sheet. SUPER easy to edit the data - no special buttons to edit/save each row.
Very nice for the user - no huge UI and clicking and messing around to edit.
And the save button code, again REALLY simple since we send the WHOLE grid edits back to the database in one simple edit!!!
(and ONE update operation for the WHOLE grid!!!).
Save button code:
protected void cmdSave_Click1(object sender, EventArgs e)
{
// pull grid rows back to table.
foreach (ListViewItem rRow in ListView1.Items)
{
int RecordPtr = rRow.DataItemIndex;
DataRow OneDataRow;
OneDataRow = rstPeople.Rows[RecordPtr];
OneDataRow["FirstName"] = ((TextBox)rRow.FindControl("txtFirst")).Text;
OneDataRow["LastName"] = ((TextBox)rRow.FindControl("txtLast")).Text;
OneDataRow["City"] = ((TextBox)rRow.FindControl("txtCity")).Text;
OneDataRow["Active"] = ((CheckBox)rRow.FindControl("Active")).Checked;
}
// now send table back to database with updates
string strSQL = "SELECT ID, FirstName, LastName, City, Active from People WHERE ID = 0";
using (SqlCommand cmdSQL = new SqlCommand(strSQL,
new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
SqlDataAdapter daupdate = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder cmdBuild = new SqlCommandBuilder(daupdate);
daupdate.Update(rstPeople);
}
}
So the trick? We persist the data table.
Then to save, you move grid back to data table, and then send the table BACK to the database in one simple update.
And the code to add a new row to the grid is ALSO very easy, we don't have to hit the database, but just add to the table, and then re-bind to the grid.
This code:
protected void cmdAdd_Click1(object sender, EventArgs e)
{
// add a new row to the grid
DataRow OneRow = rstPeople.Rows.Add();
ListView1.DataSource = rstPeople;
ListView1.DataBind();
}
So, notice how we save world poverty, save buckets of code, save buckets of mark-up, and we save buckets of messy UI in which the user has to hit edit/save over and over JUST to edit a few rows.
So, save code, save money, same markup, save messy user interface, provide a MUCH better and seamless user experience.
What more could you want?
Note how we defined the data table at the web page class level - by persisting that data table, then we get all of the wonderful and easy to use benefits above - including MUCH less code, much less markup, and much less user interaction required to edit a few simple rows of data.
And we ONLY send ONE update back to the database to save all rows - all of the dirty work here is thus done by .net for you, and you even wind up with not only MUCH less code, but we hit the database MUCH less for the update.
I did not add a un-do-edits button, but all it would do is call loadGrid again, and that would just re-load the data gain - and thus un-do any of our edits.
(so a un-do button would be a good idea here.)

How to return asp:repeater count

I have searching implemented in my app, and it goes to a results page where the results populate a table through an asp:repeater. I'll include the code below.
C#
namespace WebApplication {
public partial class SearchResults : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (Request.Params["searchterm"] != null) {
ResultLabel.Text = "Search results for: " + Request.Params["searchterm"];
string searchTerm = Request.Params["searchterm"];
int results = 0; //If I were to set it on back end
string constr = ConfigurationManager.ConnectionStrings["CurrencyDb"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr)) {
using (SqlCommand cmd = new SqlCommand("dbo.SearchProc", con)) {
try {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#SearchTerm", searchTerm);
con.Open();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
sda.Fill(ds);
ResultsTableRepeater.DataSource = ds;
ResultsTableRepeater.DataBind();
}
catch (SqlException sqlex) {
throw new Exception("SQL Exception loading data from database. " + sqlex.Message);
}
catch (Exception ex) {
throw new Exception("Error loading results data from database. " + ex.Message);
}
}
}
}
}
}
}
asp.net
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<br />
<br />
<br />
<br />
<asp:Label ID="ResultLabel" runat="server"></asp:Label>
<br />
<br />
<br />
<br />
<asp:Repeater ID="ResultsTableRepeater" runat="server">
<HeaderTemplate>
<table class="td-table-bordered">
<th>Currency Id</th>
<th>Component</th>
<th>Version</th>
<th>Vendor</th>
<th>Tech Owner</th>
<th>Tech Contact</th>
<th>Fiscal Consideration</th>
<th>Currency Status</th>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("CurrencyId") %></td>
<td><asp:HyperLink ID="UpdateLink" NavigateUrl='<%# Eval("CurrencyId", "http://10.155.54.101/Update?CurrencyId={0}") %>' runat="server" Target="_blank"><%# Eval("Model") %></asp:HyperLink></td>
<td><%# Eval("Version") %></td>
<td><%# Eval("Vendor") %></td>
<td><%# Eval("Tech Owner") %></td>
<td><%# Eval("Tech Contact") %></td>
<td><%# Eval("FiscalConsideration") %></td>
<td><%# Eval("Status") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
<asp:Label ID="StatusLabel" runat="server" Text="Label"></asp:Label>
</FooterTemplate>
</asp:Repeater>
<br />
</asp:Content>
What I would like to do is print a number how many results were returned in the footer. But I can't seem to find a way to do that throughout all of my searching, despite it seeming like it should be a simple task.
Is there a way, whether it be in the C# code behind or in the aspx directly to print how the amount of results at the end? It would be easy if there were a while(reader.read) loop to increment a counter, however that's not the case.
Thanks in advance so much for your help!
You can use the return value of sda.Fill(ds);:
As the documentation for Fill says:
Return Value: The number of rows successfully added to or refreshed in the DataSet.
Thus:
int rowsReturned = sda.Fill(ds);
Then you can assign the value in the footer.
Here is a similar issue here:
Determine the repeater row count in asp.net
Hope this helps you out! Should just be able to use their solution anywhere in your codebehind to get the Count, and then display it where ever you need it in your footer (assuming your repeater is already populated when you try to get the count).

Display result if text matches data in an XML file in C#

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;

NavigateUrl on Repeater ASP.net

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
}

Gridview paging in ModalPopupExtender strange behaviour

I have a modalpopypextender that contains a grid view and I want populate it on button click which does this:
protected void btnViewRecipients_Click(object sender, EventArgs e)
{
ModalPopupExtender1.Show();
BindData();
}
Which is straight forward. BindData does this:
protected void BindData()
{
try
{
SqlCommand sqlCommand = new SqlCommand();
string connectionString = "Data Source=SERVER\\DB1;Initial Catalog=Survey;User ID=abcde;Password=12345;";
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "Select * From [Survey].[dbo].[data]";
SqlDataAdapter sda = new SqlDataAdapter(sqlCommand.CommandText, connectionString);
SqlCommandBuilder scb = new SqlCommandBuilder(sda);
//Create a DataTable to hold the query results.
//Fill the DataTable.
sda.Fill(dTable);
//Set the DataGridView DataSource.
gvRecords.DataSource = dTable;
gvRecords.DataBind();
sqlConnection.Close();
}
}
catch (SqlException ex)
{
//Console.WriteLine(ex.StackTrace);
}
}
Now this all works good and I get to see the grid with data. I then turned on autopaging and went ahead to create the call gvRecords_PageIndexChanged. I have also turned on EnableSortingAndPagingCallbacks.
protected void gvRecords_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvRecords.PageIndex = e.NewPageIndex;
gvRecords.DataSource = dTable;
gvRecords.DataBind();
}
This kinda works very strangely. I noticed that when I click a page number, the table becomes blank and shows me EmptyDataText that I defined earlier. But when I close the ModalPopupExtender and open it again (clicking the button again) it shows me the right page and data! e.g. if I clicked page 3, then get a blank table, now reopening the MPE will show me page 3's contents in a gridview. I guess that's the viewstate stored somewhere but why is it that the gridview will not show me the page right away?
I am really stuck at this and failing to understand what I'm missing!
Any help appreciated million times, I have searched and searched online for this but maybe it is so trivial and obvious that no one has ever needed to ask!?!
Edited I've been working with Modals, UpdatePanels and ListViews for years, we'll solve this, but it would be good to see the entire markup.
From your comments I'd suggest;
Put your entire modal markup in the UpdatePanel. Make sure to set the ID and UpdateMode to conditional;
<asp:UpdatePanel ID="upModal" runat="server" UpdateMode="Conditional">
<ContentTemplate>
</ContentTemplate>
</asp:UpdatePanel>
I usually use an ASP:Panel as my DIV inside my update panel;
<asp:Panel ID="pnlPopup" runat="server" CssClass="ModalPanel">
Then place your GridView (or in my case ListView) in your panel
In your code behind after you call your gvRecords.Databind(), call upModal.Update()
protected void gvRecords_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvRecords.PageIndex = e.NewPageIndex;
gvRecords.DataSource = dTable;
gvRecords.DataBind();
upModal.Update();
}
I got it working finally, I have had to set PopupControlID to upModal, the updatepanel's ID, as opposed to the inner panel. The targetcontrolID also had to point to a hidden button, as many have found you must when working with MPEs...
Anyway, here goes:
<asp:Button ID="hiddenButton" runat="server" Text="" style="display:none;" />
<ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender1" runat="server" Enabled="True" TargetControlID="hiddenButton" PopupControlID="upModal" BehaviorID="modalbehavior" BackgroundCssClass="modalBackground" OnCancelScript="cancelClick();" CancelControlID="closePopup">
</ajaxToolkit:ModalPopupExtender>
<asp:UpdatePanel runat="server" ID="upModal" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel id="pnlPopup" runat="server" class="ModalPanel" >
<table cellpadding="5" cellspacing="5" class="topBanner" style="width:100%;">
<tr>
<td width="50">
<asp:LinkButton ID="closePopup" runat="server" onclick="LinkButton1_Click" CssClass="ClosePopupCls">Close
[x]</asp:LinkButton>
</td>
<td align="center">
<asp:Label ID="lbl" runat="server" Text="Status"></asp:Label>
</td>
<td width="25">
</td>
</tr>
<tr>
<td colspan="3">
<asp:GridView ID="gvRecords" runat="server" AllowPaging="True"
BackColor="White" EmptyDataText="No Record Found"
EnableSortingAndPagingCallbacks="True" ForeColor="GrayText" Height="600"
onpageindexchanging="gvRecords_PageIndexChanging" Width="800">
</asp:GridView>
</td>
</tr>
</table>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>

Categories

Resources