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.
Related
I have the examples of data saved in the database as shown in the figure:
list of attachments uploaded by 3 different users (STAFF_145, STAFF_143 and STAFF_147)
When I called it from gridview list, it shows like this:
Gridview of list attachment
Based on the gridview, I tried to apply the "Attachments & TRF" column with <asp:Label ID="txt_training_attach_name" runat="server" Text='<%# Bind("training_attach_name") %>' ReadOnly="true">.
It shows error when I've change to "Dropdownlist" instead of using "Label" or "Textbox".
System.ArgumentOutOfRangeException: ''txt_training_attach_name' has a
SelectedValue which is invalid because it does not exist in the list
of items. Parameter name: value'
The error points out at here when I used Dropdownlist:
if (dt.Rows.Count > 0)
{
Grid_Attachment.DataSource = dt;
Grid_Attachment.DataBind();
}
It is possible if I want to make a gridview as shown as like this?
Dropdownlist and Merge Column
I've try many ways since last month but I still cannot get the answer. Appreciate if you could help me. Thank you in advanced.
You don't mention if the staff table of up-loaded files is a different table then the one that supposed to drive the grid.
if it is for some reason, then build a group by query that does not include the file(s) column, and group by so you wind up with a SINGLE row for each staff member.
So, then we can drop in a grid list this:
And I am going to use a listbox in place of a combo (dropdown), so it will NICE display the files - you can change that to a dropdown if you want - same code
So, the markup might be this:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table table-hover" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="Firstname" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="TrainingDate" HeaderText="Training Date" DataFormatString="{0:yyyy-MM-dd}" />
<asp:BoundField DataField="ApplicationDate" HeaderText="Application Date" DataFormatString="{0:yyyy-MM-dd}" />
<asp:BoundField DataField="ProgramTitle" HeaderText="Program Title" />
<asp:BoundField DataField="TrainingCost" HeaderText="Training Cost" DataFormatString="{0:c}" />
<asp:TemplateField HeaderText="Documents Submitted">
<ItemTemplate>
<asp:ListBox ID="cboFiles" runat="server" Width="200PX"
DataTextField ="FileName"
DataValueField="FileName">
</asp:ListBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Note how we added a listbox (as noted, use a drop down if you want).
So, the code to fill this gv would thus be this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
GridView1.DataSource = MyRst("SELECT * from Users ORDER BY FirstName");
GridView1.DataBind();
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
However, for each row, we need to load up the list of files for that one row. As noted, I don't know if you have two tables here - or one. (but, it really does not matter - as noted, use a group-by for this main grid data source.
Now, the only extra part is to use the gv "row data bound" event. This fires for each row during render, and is the idea event to load up the combo or list box.
That code is thus this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get PK row id (user id)
int? PKID = GridView1.DataKeys[e.Row.RowIndex]["ID"] as int?;
string strSQL = "SELECT FileName FROM MyFiles WHERE User_ID = " + PKID;
DataTable rstFiles = MyRst(strSQL);
ListBox cboFiles = e.Row.FindControl("cboFiles") as ListBox;
cboFiles.DataSource = rstFiles;
cboFiles.DataBind();
cboFiles.Rows = 1;
if (rstFiles.Rows.Count > 1)
cboFiles.Rows = rstFiles.Rows.Count;
}
}
And above I do have two columns. One is JUST file name, and one column is the full path name + file to the up-load folder. If you don't have just a file name column, then we can write a bit of code to JUST include + show file name.
the results of running the above is thus this:
I'm trying to create a web page with the aps.net framework and I connect to the SQL server successfully and I want to display the data from the database in the Grid View and there are a search box and dropdown list but there is an error when I try to search
this is the error message:
Both DataSource and DataSourceID are defined on 'GridView1'. Remove one definition.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Both DataSource and DataSourceID are defined on 'GridView1'. Remove one definition.
and my code viewpage1.aspx
the GridView
<asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px" CellPadding="3" ForeColor="Black" GridLines="Vertical" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" Format="dd/MM/yyyy" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="InvoiceID" DataSourceID="SqlDataSource3">
<AlternatingRowStyle BackColor="#CCCCCC" />
-and this the sqldatasource
<asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:connStr %>" SelectCommand="Select * from [Portal].[fn_GetInvoices] (#SearchText) where CompanyCode=#CompanyCode and InvoiceDate between #fromDate and #toDate">
<SelectParameters>
viewpage1.aspx.cs
sqlcomm.CommandText = sqlquery;
sqlcomm.Connection = sqlconn;
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(sqlcomm);
adapter.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
This is a common error message.
I OFTEN use the wizards to build a gridview I use this:
From above, I choose create new data source.
I let the wizard run.
BUT THEN we wind up with some MESSAY sqldatasource in the web page. I do NOT like them, and they NEAR ALWAYS just cause you pain.
So, what I will then do this:
Remove the sqldata source from the web markup - you don't' need that mess anyway.
eg this:
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:CSharpWebApp.Properties.Settings.TEST4 %>"
SelectCommand="SELECT [ID], [Fighter], [Engine], [Thrust], [Description], [ImagePath]
FROM [Fighters]"></asp:SqlDataSource>
DELETE the above!!!!
Now WHEN you WILL use code to load up the Gridview? Then you ALSO must turn off (remove) the fact that you NOT GOING to use the sql data source anymore.
So in your GV, remove this:
So, all that error message is telling you is you are trying to set the data source in "code" but you ALREADY have a sql datasource setup in the markup.
So, get in the habit of blowing out and removing the sqldata source on the page, and ALSO remove the GV data source setting in the markup.
So, now say I will have this GV, and NOT have ANY data source in the markup in the web page. (and I recommend you do this). So, I still VERY often use the wizards. Even for a dropdown list, a gridview, repeaters, and even listview (my favorite).
So, run wizards - build the markup
Then blow out (remove) the SqlDataSource, and the
DataSourceID="SqlDataSource1" from the control (in this case gv).
So, as noted, you cannot have BOTH a DataSourceID="SqlDataSource1" and THEN try to use code. It is one or the other - and that's what the error message is telling you.
So, now we have this markup:
(and the wizards generated most of this for me!!!)
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
<asp:BoundField DataField="Fighter" HeaderText="Fighter" />
<asp:BoundField DataField="Engine" HeaderText="Engine" />
<asp:BoundField DataField="Thrust" HeaderText="Thrust" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:ImageButton ID="btnImage" runat="server" Height="68px" Width="149px"
OnClientClick ="popimage(this);return false"
ImageUrl = '<%# Eval("ImagePath") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Just nice clean markup - no Sqldatasource junk.
Now we are free to write normal code like a normal human, and we can fill the grid like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from Fighters", conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And our results are now this:
Ok, so now lets add a search box above the GV to search the GV.
Say you can type in the first few chars of the Fighter jet name, and we want to filter by that:
So, drop in a text box above the GV, + search button.
We now have say this:
<asp:Label ID="Label1" runat="server" Text="Search for Fighter jet" Font-Size="Large"></asp:Label>
<asp:TextBox ID="txtSearch" runat="server" Style="margin-left:15px" Font-Size="Large"></asp:TextBox>
<asp:Button ID="cmdSearch" runat="server" Text="search"
style="margin-left:15px" CssClass="btn"
/>
<br />
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
So, now the page with searching looks like this:
Say we search for Lockheed - but even just typing in Lock would be fine.
thus:
And now our code can say be this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid("");
}
void LoadGrid(string MySearch)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from Fighters ", conn))
{
if (MySearch != "")
{
cmdSQL.CommandText += #" WHERE Fighter LIKE #Fighter + '%'";
cmdSQL.Parameters.Add("Fighter", SqlDbType.NVarChar).Value = MySearch;
}
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
protected void cmdSearch_Click(object sender, EventArgs e)
{
LoadGrid(txtSearch.Text);
}
}
So, I am STRONG suggesting that you DUMP the sqldata source on the web page markup. Such Sqldata soruces on the page can be great for one time load or data display. But the VERY instant you want control, filters, and need to use code?
Quite much the SAME instant it is time to drop and toss out and remove the data source from the web markup. You be glad you did, and as you can see, you now have 100% EASY AND SIMPLE control of the data you shove into the GV, and that includes endless possible use of simple code and buttons to add filters etc. to that data.
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.
I tried looking this one up online, but I guess I'm not sure how I should phrase the question without a full explanation.
I've got a webform with a search bar. When you enter in a search term, it queries a database and pulls information and populates a gridview. I'm using the following code:
string find = "SELECT tblShipments.ShipmentID as [Shipment ID], tblShipmentsAssets.DateShip as [Date Shipped], FROM tblShipments INNER JOIN(tblAssets INNER JOIN tblShipmentsAssets ON tblAssets.AssetID = tblShipmentsAssets.AssetIDFK) ON tblShipments.ShipmentID = tblShipmentsAssets.ShipmentIDFK where(AssetIDFK like '%' + #assetidfk + '%' )";
OleDbCommand comm = new OleDbCommand(find, con);
comm.Parameters.Add("#assetidfk", OleDbType.Char).Value = TxtSearch.Text;
con.Open();
comm.ExecuteNonQuery();
OleDbDataAdapter da = new OleDbDataAdapter();
da.SelectCommand = comm;
DataSet ds = new DataSet();
da.Fill(ds, "AssetIDFK");
SearchGridView.DataSource = ds;
SearchGridView.DataBind();
In the past, I've simply populated a gridview solely with aspx code using <asp:SqlDataSource> and there I was able to get at the columns that held dates withing the <columns> tag and add in a DataFormatString="{0:d}" to get the format I wanted:
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" HorizontalAlign="Center">
<Columns>
<asp:BoundField DataField="NextCal" HeaderText="Calibration Due" DataFormatString="{0:d}" >
</asp:BoundField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Database %>" ProviderName="<%$ ConnectionStrings:Database.ProviderName %>" SelectCommand="SELECT , [NextCal] FROM [tblAssets]"></asp:SqlDataSource>
With my C# method of populating the gridview, I have no <Columns> section to change the data format. I would then assume I need to do this in the code behind, however I'm not sure how to do that.
Figured out what I was doing wrong:
By having <AutoGenerateColumns ="true">, my columns were (big surprise) being automatically generated and then me adding in columns under the tag in .aspx was generating duplicate columns.
I changed it to <AutoGenerateColumns ="false">, manually entered my columns in under the tag and used the DataFormatString="{0:MM/dd/yyyy hh:mm tt}"to change the date format.
Sorry for the dumb question. Hopefully this will help someone avoid the same mistake..
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;