Not able to insert edited data from Gridview - c#

Using GridView I am trying to insert all the records, including the edited column into the database, by clicking the submit button. However, it is always inserting the initial data which was fetched from the database after the page load.
I want user to edit the column 'id', and after clicking on submit button, all the records should be inserted into a table. With the current code, the insertion is happening, however in id column, I always get "MG_US-FCWI1.05.30" and "MG_US-FCWI1.05.10" in DB. But I want "MG_US-FCWI1" and "MG_US-FCW" to be inserted. I am using VS2013.
Code used -
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="column_name" HeaderText ="Material Name" />
<asp:BoundField DataField="part number" HeaderText ="Material Number" />
<asp:TemplateField HeaderText="Id">
<ItemTemplate>
<asp:TextBox ID="txtedit" runat="server" Text='<%# Eval("id") %>' ReadOnly="false"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="GL_account" HeaderText ="GL Account" />
</Columns>
</asp:GridView>
<asp:Button ID="btnUpload" Text="Submit" runat="server" OnClick="Submit_Data" Height="21px" style="margin-left: 260px; margin-top: 14px;" />
protected void Submit_Data(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
SqlConnection con = new SqlConnection(getConn());
SqlCommand com = new SqlCommand("insert into test ([Sales Order Id],[input data],Material_Name,[Part Number],id,GL_Account) values (" + sales_order_id + "," + input_id + ",'" + row.Cells[0].Text + "','" + row.Cells[1].Text + "','" + ((TextBox)row.Cells[2].FindControl("txtedit")).Text + "','" + row.Cells[3].Text + "')", con);
con.Open();
com.ExecuteNonQuery();
con.Close();
}
}

This is a REALLY good example as to why you don't want to concatenate that long string (reduces SQL injection issues - but ALSO allows for easier to read and easier to write code).
it beyond hard to read, and thus cleaning this up?
Then the error(s) in the code become clear.
You have this:
((TextBox)row.Cells[2].FindControl("txtedit")).Text
but, it should be this:
((TextBox)row.FindControl("txtedit")).Text
Lesson: Make your code readable, and you find your bugs and issue a lot faster.
Say something like this:
foreach (GridViewRow row in GridView1.Rows)
{
SqlCommand com = new SqlCommand("insert into test " +
"([Sales Order Id],[input data],Material_Name,[Part Number],id,GL_Account)" +
"(#SalesID,#InputData,#MatName,#PartNum,#id,#GLAccount)",
new SqlConnection(getConn()));
com.Connection.Open();
com.Parameters.Add("#SalesID", SqlDbType.Int).Value = sales_order_id;
com.Parameters.Add("#InputData", SqlDbType.Int).Value = input_id;
com.Parameters.Add("#MatName", SqlDbType.NVarChar).Value = row.Cells[0].Text;
com.Parameters.Add("#PartNum", SqlDbType.Int).Value = row.Cells[1].Text;
com.Parameters.Add("#GlAccount", SqlDbType.NVarChar).Value = ((TextBox)row.FindControl("txtedit")).Text;
com.ExecuteNonQuery();
com.Connection.Close();
}
I don't think you need a Convert.ToInt32() around the int values.
But, by just re-writing the code as readable, then the findcontrol error was easy to spot. Also, note how we don't have to guess if we need extra quotes around strings, or not for numbers - so we strong casting here, and that also works better.
Now above is air code, but after I had typed the first parameter, then I started hitting ctr-d to duplicate the line - so the amount of typing I had to do was actually quite small - between intellisense and Ctrl-d, then typing was reduced, but the code is not only easier to read, but we could for example add another row/parameter set over time, and again modifying this code would be less taxed on your carbon based computer (your brain) as opposed to the computer based silicon brain.

Related

Submitting multiple rows in gridview with Checkboxes (C#)

I am aiming to get data:
From an sql database
To a gridview
To a local table
So far, I am able to use a stored procedure to display the sql data to a gridvew and I am also able to use checkboxes to send the data to a local table.
Issue:
Only one row's data is being submitted to the table, despite the number of checkboxes checked.
ex. I click 3 checkboxes, wanting to get 3 different rows of data to the table. I hit the submit button and when I check the table, only one of the "checked" rows is submitted to the table 3 times.
EDITED Code:
protected void btnSubmit_Click(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["localDataB"].ConnectionString;
using (var sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
string insertStatement = "INSERT into LocalDB (Item1, Item2, Item3)" + "(#Item1, #Item2, #Item3)";
string Data1, Data2;
float Data3;
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox ckSel = (gRow.FindControl("checker") as CheckBox);
if (ckSel.Checked)
{
Data1 = Convert.ToString(gRow.Cells[1].Text);
Data2 = Convert.ToString(gRow.Cells[2].Text);
Data3 = Convert.ToInt32(gRow.Cells[3].Text);
using (var sqlCommand = new SqlCommand(insertStatement, sqlConnection))
{
sqlCommand.Parameters.Add("Item1", SqlDbType.Text).Value = Data1;
sqlCommand.Parameters.Add("Item2", SqlDbType.Text).Value = Data2;
sqlCommand.Parameters.Add("Item3", SqlDbType.Float).Value = Data3;
sqlCommand.ExecuteNonQuery();
}
}
}
}
GVbind();
Code for checkbox inside grid:
<asp:GridView ID="GridView1" runat="server" EmptyDataText="No Data Found" BackColor="#CCCCCC" BorderColor="#999999" BorderStyle="Solid" BorderWidth="3px" CellPadding="4"
AutoGenerateColumns="False" CellSpacing="2" ForeColor="Black" DataKeyNames="Data1" Width="70%" Visible="False" ShowFooter="True">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:Label ID="SelectBox" runat="server" Text="Select"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="checker" runat="server" OnCheckedChanged="checker_CheckedChanged"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Data1" HeaderText="Title1" ReadOnly="True" />
<asp:BoundField DataField="Data2" HeaderText="Title2" ReadOnly="True" />
<asp:BoundField DataField="Data3" HeaderText="Title3" />
</Columns>
</asp:GridView>
Ok, it not at all clear what your routine checker_CheckedChanged() does?
You don't need a post-back or anything for the check boxes - but ONLY the one submit button and code stub
. Those data1, data2 etc. will NOT persist in memory anyway. So, you can't use that routine - but you don't need it either.
Unless the grid has multiple pages etc., then dump that routine. You are free to check box any row in the grid. You then have one submit button code, and that routine just needs a bit of change to check all GV rows, and save the check box values.
That submit button code thus can/will look like this:
protected void btnSubmit_Click(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["localDataB"].ConnectionString;
using (var sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
// insert any row with check boxes into temp db
string insertStatement = "INSERT into LocalDB (Item1, Item2, Item3) " +
"values (#Item1, #Item2, #Item3)";
bool Data1, Data2, Data3;
foreach (GridViewRow gRow in GridView1.Rows)
{
Data1 = Convert.ToBoolean(gRow.Cells[0].ToString());
Data2 = Convert.ToBoolean(gRow.Cells[1].ToString());
Data3 = Convert.ToBoolean(gRow.Cells[2].ToString());
// save data if ANY is checked
if (Data1 | Data2 | Data3)
{
using (var sqlCommand = new SqlCommand(insertStatement, sqlConnection))
{
sqlCommand.Parameters.Add("#Item1", SqlDbType.Bit).Value = Data1;
sqlCommand.Parameters.Add("#Item2", SqlDbType.Bit).Value = Data2;
sqlCommand.Parameters.Add("#Item3", SqlDbType.Bit).Value = Data3;
sqlCommand.ExecuteNonQuery();
}
}
}
}
GVbind();
}
I don't see the need for your first routine. The submit button can loop the GV, get the check box values, and if any one of the 3 is checked, then you do the insert.
However, keep in mind that the cells[] collection ONLY works for datafields if you using a templated control and REAL check box, then you need to use findcontrol, and NOT the cells[] collection
Edit:
Ok, first, information provided suggests that a template field is being used.
HOWEVER, we will first address the CheckBoxField code, since it HARD to google and find that answer. So I going to include that answer.
If a check box is a datafield, then you can't change/edit, but you STILL MAY want to iterate over the GV, and get those values.
So, for data fields, say like this:
<asp:CheckBoxField DataField="Active" HeaderText="Active" />
Then our code has to work like this (you have to dig deeper into cells() colleciton.
So, code becomes this:
foreach (GridViewRow gRow in GridView1.Rows)
{
Data1 =(gRow.Cells[0].Controls[0] as CheckBox).Checked;
Data2 = (gRow.Cells[1].Controls[0] as CheckBox).Checked;
Data3 = (gRow.Cells[2].Controls[0] as CheckBox).Checked;
Note how a CheckBoxField requires us to use controls.
However, as noted, with template field (any kind and ANY of them?).
WE DO NOT use the Cells[] collection and templated columns DO NOT appear in the cells collection.
And thus, in a lot (probably most) cases, then we can expect to have a CheckBox control dropped into the markup as a templated field.
Typical looks like this:
<asp:GridView ID="GridView1" runat="server" class="table borderhide"
AutoGenerateColumns="false" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" HeaderStyle-Width="200" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Smoking" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkSmoking" runat="server"
Checked='<%# Eval("Smoking") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Balcony" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkBalcony" runat="server"
Checked='<%# Eval("Balcony") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
So in above, the first values (bound fields) WILL BE found in cells colleciton.
However, the templated fields above? we have to do this:
"WHERE ID = #ID";
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox cSmoke = (CheckBox)gRow.FindControl("chkSmoking");
CheckBox cBlacony = (CheckBox)gRow.FindControl("chkBalcony");
int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Parameters.Add("#S", SqlDbType.Bit).Value = cSmoke.Checked;
cmdSQL.Parameters.Add("#B", SqlDbType.Bit).Value = cBlacony.Checked;
cmdSQL.Parameters.Add("#ID", SqlDbType.Int).Value = PKID;
cmdSQL.ExecuteNonQuery();
}
}
So, our code then becomes this:
foreach (GridViewRow gRow in GridView1.Rows)
{
Data1 =(gRow.FindControl("Active") as CheckBox).Checked;
Data2 = (gRow.FindControl("Smoking") as CheckBox).Checked;
Data3 = (gRow.FindControl("Balcony") as CheckBox).Checked;
Now of course, you replace the "Text control" id with YOUR data 1, 2, and 3 id that you used.
The rest of the code should be the same.
BIG LESSON OF THE DAY?
Post a wee bit of markup - not a huge boatload - but just a few lines next time. You save world poverty, and I would have been able to post a better answer next time.
So the rule is:
DataBound fields - use cells[] collection.
Templated fields - you have to using .FindControl("name of control id goes here")
Edit#2
Ok, so far, the question is now this:
We have some data. If the user checks the row 1, or 5 or 10 rows, for each of the checked rows, I want to write out the columns/values I have in 3 other columns item1, item2, item3?
Simple queston!!!!
Ok, so the ONLY missing information is WHAT data type field type is item1, item2, and item3? We only really are missing that part.
So, if check box = true, write out those 3 item columns to the new temp table.
So, the code now should be:
bool Data1, Data2, Data3;
foreach (GridViewRow gRow in GridView1.Rows)
{
// get check box -
CheckBox ckSel = (gRow.FindControl("checker") as CheckBox);
// save data if ANY is checked
if (ckSel.Checked)
{
Data1 = Convert.ToBoolean(gRow.Cells[0].Text);
Data2 = Convert.ToBoolean(gRow.Cells[1].Text);
Data3 = Convert.ToBoolean(gRow.Cells[2].Text);
using (var sqlCommand = new SqlCommand(insertStatement, sqlConnection))
{
sqlCommand.Parameters.Add("#Item1", SqlDbType.Bit).Value = Data1;
sqlCommand.Parameters.Add("#Item2", SqlDbType.Bit).Value = Data2;
sqlCommand.Parameters.Add("#Item3", SqlDbType.Bit).Value = Data3;
sqlCommand.ExecuteNonQuery();
}
}
}
As noted, I stated MULTIPLE TIMES NOW, that non templated columns STILL MUST use cells collection. ONLY templated columns can and need to use FindControl. All others MUST continue to use .Cells[] collection.
It should be like this;
sqlCommand.Parameters.AddWithValue("#Item1", data1);
sqlCommand.Parameters.AddWithValue("#Item2", data2);
sqlCommand.Parameters.AddWithValue("#Item3", data3);

Copy Paste a row in a asp:GridView using C# in a web application

So I have a web application that uses a GridView.
We currently add 1 new blank record at a time fill it in and move on. There are times when the data needing to be entered has several fields that need to be duplicated. Is there a way to add a blank row, fill it in , and then copy that row and paste it back into the GridView?
I've looked at clone, but i haven't seen anything that works in a web application. Thanks for any advice.
Well, one way, is you could add a copy button to the grid?
Say we have this grid:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID"
cssclass="table table-hover borderhide">
<Columns>
<asp:TemplateField HeaderText ="First Name">
<ItemTemplate>
<asp:TextBox ID="txtFirst" runat="server" Text = '<%# Eval("FirstName") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Last Name">
<ItemTemplate>
<asp:TextBox ID="txtLast" runat="server" Text = '<%# Eval("LastName") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="City">
<ItemTemplate>
<asp:TextBox ID="txtCity" runat="server" Text = '<%# Eval("City") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Active">
<ItemTemplate>
<asp:CheckBox ID="Active" runat="server" Checked = '<%# Eval("Active") %>'></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Copy">
<ItemTemplate>
<asp:ImageButton ID="cmdCopy" runat="server" Text="Copy"
ImageUrl="~/Content/copy1600.png" Height="32px" Width="32px"
OnClick="cmdCopy_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<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 />
So, code to load this grid up
private DataTable rstPeople = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadGrid();
ViewState["MyTable"] = rstPeople;
}
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());
GridView1.DataSource = rstPeople;
GridView1.DataBind();
}
}
And the add row button code:
protected void cmdAdd_Click1(object sender, EventArgs e)
{
GridToTable(); // user may have edits
// add a new row to the grid
DataRow OneRow = rstPeople.NewRow();
OneRow["Age"] = 0;
OneRow["Active"] = true;
rstPeople.Rows.Add(OneRow);
GridView1.DataSource = rstPeople;
GridView1.DataBind();
}
So we click on add row, and that gives us this:
So, we have that blank row. But, in place of add row, we could click the copy button, and that would add a row - but copy from current. (I suppose we could have a copy + paste button - but that's WAY TOO much UI here).
So, add row = add blank row.
but, copy row button - add row - copy.
The code for that looks like this:
protected void cmdCopy_Click(object sender, ImageClickEventArgs e)
{
GridToTable(); // user might have done some editing
ImageButton cmdCopy = (ImageButton)sender;
GridViewRow gvRow = (GridViewRow)cmdCopy.Parent.Parent;
DataRow CopyFrom = rstPeople.Rows[gvRow.RowIndex];
DataRow OneRow = rstPeople.NewRow();
OneRow["Age"] = 0;
OneRow["FirstName"] = CopyFrom["FirstName"];
OneRow["LastName"] = CopyFrom["LastName"];
OneRow["City"] = CopyFrom["City"];
OneRow["Active"] = CopyFrom["Active"];
rstPeople.Rows.Add(OneRow);
GridView1.DataSource = rstPeople;
GridView1.DataBind();
}
Now I not shared how teh save button works.
So, the user now can add new rows. Tab around - edit any row. or even copy a new row (and again, edit some more).
So save the whole mess and grid back to the database, we
Send Grid back to table
Send table back to database.
So the save all button is thus this:
protected void cmdSave_Click1(object sender, EventArgs e)
{
GridToTable();
// 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);
}
}
again, really simple. And note how we did not bother with templates etc. (too messy, and really not less code then above).
I suppose you could have for a new row a "paste" icon, but if the users going to have to pick a row and copy - might as well make it "add row + copy" in one operation.
(and it not really a copy button, but more of a "duplicate row" button.
Only routine not posted was the GridToTable. This works, since we always persist the table, but any edits in GV have to be send back to the table, and thus we use this:
void GridToTable()
{
// pull grid rows back to table.
foreach (GridViewRow rRow in GridView1.Rows)
{
int RecordPtr = rRow.RowIndex;
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;
}
}
As noted I suppose you could drop in a "copy" button, and ONLY persist + save the row index, and then have a paste button - this would allow a cut + paste between any rows, and not be limited to just new rows. (but, that would allow the user quite easy to over-write a existing row - again UI overload from user training point of view.
The above trick is quite slick, since any new rows, any edits are sent back to the database in one simple Update operation. (and the provider is smart - if a row was not touched or changed, then sql update statements are not generated.
This whole trick works due to persisting the table in ViewState. Be warned, if you have a datapager, then you would have to call GridToTable in such navigation, or in fact execute a save command.
Also note how we picked up the .parent.parent (grid row) and again did not bother with teh GV event model. And without a gazilion template stuff, we also saved world poverty in terms of not having to mess with mutiple templates.
In fact, for any grid beyond the above, I use the exact same above approch, but perfer a ListView. The reason is that you can just drag + drop in standard asp.net controls, and you don't have to needless surround them with "item template" which again is too much work and effort.

c# Cannot Convert from string to int

I have a gridview that populates from an SQL table and shows two columns, one comes from an integer data column, the other from an nvarchar. Gridview also has a checkbox column
The gridview populates correctly, and after a subset of rows is selected (via checkbox column) I want to insert the selected rows into another SQL table. When populating the variables for the SQL statement however I get the "Cannot Convert from string to int" error on the value that is populated from an int to begin with.
I have tried writing up convert and parse for this statement but still getting the error:
cmd.Parameters.AddWithValue("#PracticeArea", int.Parse(row.Cells["Id"].Value));
cmd.Parameters.AddWithValue("#PracticeArea", Convert.ToInt32(row.Cells["Id"].Value));
cmd.Parameters.AddWithValue("#PracticeArea", Convert.ToInt32(row.Cells["Id"].Text));
All still show the error on the ["Id"] value.
Any thoughts?
Example of the data that is being populated to the gridview is:
PracticeID PracticeName
1 General Surgical Pathology
2 General Pathology/Basic Science
4 Cardiovascular
6 Cytopathology-GYN
7 Cytopathology-nonGYN
Full button command is:
protected void Bulk_Insert(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
if ((row.FindControl("CheckBox1") as CheckBox).Checked)
{
string connectionString = WebConfigurationManager.ConnectionStrings["CS1"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
{
using (SqlCommand cmd = new SqlCommand("INSERT INTO ReviewerPractice VALUES(#Reviewer, #PracticeArea)", con))
{
cmd.Parameters.AddWithValue("#Reviewer", ReviewerName.Text);
cmd.Parameters.AddWithValue("#PracticeArea", Convert.ToInt32(row.Cells["Id"].Value));
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
}
}
Full Gridview control is:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Id" HeaderText="Id" ItemStyle-Width="30" />
<asp:BoundField DataField="PracticeName" HeaderText="PracticeName" ItemStyle-Width="150" />
</Columns>
</asp:GridView>
<br />
<asp:Button ID="Button1" Text="Add Practice Areas" OnClick="Bulk_Insert" runat="server" />
Hope this answers (some?) of the questions from all the comments to date.
The problem is that row.Cells[] is an array, so you need to use it like this:
row.Cells[3].Text
And it's better to use the Parameters for sql like this:
cmd.Parameters.Add("#PracticeArea", SqlDbType.Int).Value = Convert.ToInt32(row.Cells[index].Text;

Row Count on Gridview

(this is another question, since my original post, I asked too many questions in one)
Let me state this first. I am pretty much completely new to ASP coding. I am working on a little side project that requires me to use ASP instead of PHP that I sort of did before. I have been looking at solutions for past 2 days, and have tried many things, but can't seem to get it to work with my code. I have been part of this site for some time, so I do know how it works. I would not be asking here if I wasn't already trying to do this on my own for some time. I have learned a huge amount of information about SQL on here, so I hope to do the same with ASP.
Question:
Number of Returned Rows display
When the page initially loads, it has only a TextBox1 and a Button. If I don't enter anything in the box and hit the button, it will load my GridView with all the Data rows from the SQL Select. When I do hit the button, I would like to display the amount of rows that has been returned next to the button.
GridView1 :
<asp:TextBox ID="TextBox1" runat="server" Width="265px" Height="22px" CssClass="myBox"></asp:TextBox>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Search Fields" CssClass="myButton" />
<asp:GridView ID="GridView1" OnPageIndexChanging="GridView1_PageIndexChanging" OnSorting="GridView1_Sorting" runat="server" AutoGenerateColumns="true" CellPadding="4" EnableModelValidation="True" EnableTheming="True" ForeColor="#333333" GridLines="None" Width="100%" style="margin-top: 0px; text-align: center;" AllowPaging="True" AllowSorting="True" >
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<EditRowStyle BackColor="#999999" />
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
</asp:GridView>
Code Behind (DB name and Password taken out):
SqlConnection vid = new SqlConnection("Data Source=ENF;Initial Catalog=***Database Name***;Persist Security Info=True;User ID=sa;Password=***Password***");
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GridView1.DataSource = GetData();
GridView1.DataBind();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
String str = "SELECT ab.NAME as [Customer] ,ISNULL(ab.TELEPHONE1,'') as [Phone #] ,ISNULL(pb.NAME,'') as [Product] ,ISNULL(aeb.NEW_PRODUCTVERSION,'') as [Version] ,CASE WHEN ab.STATUSCODE = 1 THEN 'Active' ELSE 'Inactive' END as [Status] ,ISNULL('Sal : ' + c.SALUTATION + ' / ','') + ISNULL('Title : ' + c.JOBTITLE + ' / ','') + ISNULL(a.PRIMARYCONTACTIDNAME,'') as [Primary Contact] ,ISNULL(c.TELEPHONE1,'') as [Contact Phone] FROM ACCOUNTBASE ab LEFT JOIN ACCOUNTEXTENSIONBASE aeb on ab.ACCOUNTID = aeb.ACCOUNTID LEFT JOIN PRODUCTBASE pb on aeb.NEW_PRIMARYPRODUCTID = pb.PRODUCTID LEFT JOIN ACCOUNT a on ab.ACCOUNTID = a.ACCOUNTID LEFT JOIN CONTACT c on a.PRIMARYCONTACTID = c.CONTACTID WHERE ((ab.NAME LIKE '%' + #search + '%') OR (aeb.NEW_PRODUCTVERSION LIKE '%' + #search + '%') OR (pb.NAME LIKE '%' + #search + '%') OR (a.PRIMARYCONTACTIDNAME LIKE '%' + #search + '%')) ORDER BY ab.NAME";
SqlCommand xp = new SqlCommand(str, vid);
xp.Parameters.Add("#search", SqlDbType.NVarChar).Value = TextBox1.Text;
vid.Open();
xp.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = xp;
DataSet ds = new DataSet();
da.Fill(ds, "Name");
GridView1.DataSource = ds;
GridView1.DataBind();
vid.Close();
}
Amount of rows that has been returned will store in instance of dataset. so by taking the count you will get the returned row information.The DataSet contains rows, columns,primary keys, constraints, and relations with other DataTable objects. We can get the number of rows from in a Table inside a Dataset by using its Rows.Count property.
ds.Tables[0].Rows.Count
I am on Linux now and I am coding in RoR.... I cannot test now...
But if you need to know how many items has your GridView, just use:
int qty = GridView1.Rows.Count;
Is it what you need?
Some samples... always find in MSDN abour Microsoft Developer info, There are a lot of stuff there!
http://msdn.microsoft.com/library/system.web.ui.webcontrols.gridviewrowcollection.count%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rows%28v=vs.110%29.aspx
To get the total rows
int TotalRecord = dt.Rows.Count();
You can probably just set everything in your OnClick event but if it doesn't work you may have to set your row count when the gridview is being created and then I would create a label and set the label = TotalRecord.text. make the label.visible=False and in your buttons onclick event set the label.visible = true.
If you don't want to show the count until the user clicks the button, this means that you are getting the count on the post back, and not on the original display of the page. But you populate the gridview on the original display. So at the time of the postback, you no longer have the dataset available, so you can't just say textbox1.text=ds.tables(0).rows.count. You would have to either (a) rerun the query, which seems like a waste of resources, or (b) stash the count somewhere on the initial load.
I'd suggest (b). You could populate the text box on the initial load and hide it (textbox1.visible=false). Or you could create a hidden field to keep the count, or put it in the view state, and then retrieve it from there when you need it.
Two by the ways:
One: I'd use meaningful names for controls rather than "textbox1" and "gridview1". It's a lot easier to read a program that says
if update_order.checked then ...
rather than
if checkbox1.checked then ...
Two: You have some unnecessary steps in your database call. You don't need the xp.ExecuteNonQuery. The fill() will execute the query. You're running it twice: the first time you throw away the results, and then the second time you process them. Also, you don't normally need to specify the data type on your parameters. You can just write
xp.parameters.AddWithValue("#search",textbox1.text)

How to get a data field in gridview to become a url

Again, I know this has been answered many a time, but I'm getting confused with all the examples. So I'll ask it in the way I need answered.
I have a sql table, supplylinks. this has rowid (identity pk), title (varchar), link (varchar) and description (varchar).
The link field is an actual hyperlink, a url.
So for arguments sake, lets say the first row is:
1 | Google | http://www.google.com | Google Search engine
Easy enough.
Now I'm loading this into a gridview.
Nothing fancy, all done in c# code.
SqlConnection conn = new SqlConnection(#"Server=DEV6\MSSQLHOSTING;Database=Intranet;Trusted_Connection=True;");
ds = new DataSet("ds");
if (type.Equals("SAIX"))
{
SqlDataAdapter da = new SqlDataAdapter("select [Title],[Link],[Description] from SupplierLinks where SuppRowID = " + index, conn);
da.Fill(ds);
}
if (type.Equals("Domian Related Links"))
{
SqlDataAdapter da = new SqlDataAdapter("select [Title],[Link],[Description] from DomainLinks where SuppRowID = " + index, conn);
da.Fill(ds);
}
if (ds.Tables.Count > 0)
{
if (ds.Tables[0].Rows.Count > 0)
{
grdLinks.DataSource = ds;
grdLinks.DataBind();
}
}
else
{
lblDisp.Text = "";
lblError.Text = "There are no links for that type";
}
Nothing wrong there. I get my info. But I want to now make the link that is returned by the sql table and put into the gridview as a proper link so that when someone clicks on the link, they are redirected to Google, in this instance.
Please help. All other coding around here is confusing me. Lots are saying I must add a hyperlink column to the gridview. But where?
I was getting so far, then got lost as to what to bind.
<asp:GridView ID="grdLinks" runat="server">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="col2"
</Columns>
</asp:GridView>
Like I said, I'm lost and confused.
Thank you in advance.
<Columns>
<asp:HyperLinkField DataTextField="LeadID" DataNavigateUrlFields="LeadID" DataNavigateUrlFormatString="LeadInformation.aspx?LeadID={0}" Text="Lead ID" />
<asp:BoundField DataField="DateTime" HeaderText="Date Updated" />
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Bind("LeadID") + Request.QueryString("type") %>' Text=""></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
Hope this will help you
all I needed was
<a href='<%# Eval("Link") %>'>
<asp:Label ID="LinkLabel" runat="server" Text='<%# Eval("Link") %>' /></a>
in my listview.

Categories

Resources