I have the following code LoadRegistrations(); to populate a DropDownList with values from a SQL database.
I will be likely to use this several times in different places so wanted to write a method to take care of it, instead of copying this method and changing minor details.
I've got as far as populating the DataTable but I'm not sure how to go about passing a DropDownList & the DataTextField + DataValueField into it and binding the data. Please explain what I have to do
Original Method
private void LoadRegistrations()
{
DataTable reg = new DataTable();
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString1"].ToString()))
{
try
{
SqlDataAdapter adapter = new SqlDataAdapter("select vehicleID, regNo from dbo.Vehicles order by regNo Asc", con);
adapter.Fill(reg);
ddreg.DataSource = reg;
ddreg.DataTextField = "regNo";
ddreg.DataValueField = "vehicleID";
ddreg.DataBind();
}
catch (Exception ex)
{
// Error handling to be done
}
}
}
New Method
private DataTable PopulateDropdown(string connectionString, DataTable datatable, string query)
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection(connectionString))
{
try
{
SqlDataAdapter adapter = new SqlDataAdapter(query, con);
adapter.Fill(dt);
//What do I do here? I want to bind to a dropdown list passed into this method
}
catch (Exception ex) { }
}
return dt;
}
ASP to generate dropdown
<asp:DropDownList ID="ddreg" CssClass="form-control" runat="server" AppendDataBoundItems="true">
<asp:ListItem Text="<Select Registration Number>" Value="0" />
</asp:DropDownList>
You've created a method with parameters:
private DataTable PopulateDropdown(string connectionString, DataTable datatable, string query)
If you want to pass a DropDownList to that method, do exactly what you already do and add a parameter:
private DataTable PopulateDropdown(string connectionString, DataTable datatable, string query, DropDownList myDropDownList)
Then in the method you can refer to myDropDownList:
myDropDownList.DataSource = dt;
myDropDownList.DataBind();
When calling the method, you'd pass it the DropDownList you want to modify:
PopulateDropDown(someConnectionString, someDataTableYouDoNotUse, someQuery, ddreg);
private DataTable PopulateDropdown(string connectionString, DataTable datatable, string query, System.Web.UI.WebControls.DropDownList yourDropdownList)
{
SqlDataAdapter adapter = new SqlDataAdapter(query, con);
adapter.Fill(dt);
yourDropdownList.DataSource = dt;
yourDropdownList.DataBind();
return dt;
}
Related
The search method is here:
private void textBox1_TextChanged(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=DESKTOP-HNR3NJB\\mysql;Initial Catalog=stock;Integrated Security=True");
SqlDataAdapter sda = new SqlDataAdapter("SELECT ProductName FROM [stock].[dbo].[Products]", con);
sda.Fill(dt);
dataGridView1.DataSource = dt;
dt.DefaultView.RowFilter = string.Format("ProductName LIKE '%{0}%'", textBox1.Text);
}
Now that does filter out the results in the table, but it adds columns like the picture below:
Search Results
Load data function (gets called as soon as the form is loaded:
public void LoadData()
{
SqlConnection con = new SqlConnection(#"Data Source=DESKTOP-HNR3NJB\mysql;Initial Catalog=stock;Integrated Security=True");
con.Open();
//reading data from sql
SqlDataAdapter sda = new SqlDataAdapter("SELECT * FROM [stock].[dbo].[Products]", con);
dt = new DataTable();
sda.Fill(dt);
dataGridView1.Rows.Clear();
foreach (DataRow item in dt.Rows)
{
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = item["ProductID"].ToString();
dataGridView1.Rows[n].Cells[1].Value = item["ProductName"].ToString();
if ((bool)item["ProductStatus"])
{
dataGridView1.Rows[n].Cells[2].Value = "Active";
}
else
{
dataGridView1.Rows[n].Cells[2].Value = "Inactive";
}
dataGridView1.Rows[n].Cells[3].Value = item["Employee"].ToString();
dataGridView1.Rows[n].Cells[4].Value = item["CPU"].ToString();
dataGridView1.Rows[n].Cells[5].Value = item["RAM"].ToString();
dataGridView1.Rows[n].Cells[6].Value = item["SSD"].ToString();
dataGridView1.Rows[n].Cells[7].Value = item["HDD"].ToString();
dataGridView1.Rows[n].Cells[8].Value = item["WindowsVersion"].ToString();
dataGridView1.Rows[n].Cells[9].Value = item["Description"].ToString();
dataGridView1.Rows[n].Cells[10].Value = item["Type"].ToString();
}
con.Close();
}
Thanks
OK, so you're filling the datagridview elsewhere. You would just need to apply the rowfilter to the view to in the textbox_textchanged event
Where you're populating your current datagridview, ensure that you have your dt instantiated in a wider scope so that the textbox event can access it and then all you should have to do in your textchanged event is the following line:
dt.DefaultView.RowFilter = string.Format("ProductName LIKE '%{0}%'", textBox1.text);
This should then limit the rows to what is currently found. Here's an example of a demo database (you will have to change this to suit your needs)
DataTable dt; //declared outside a method so that multiple methods have access to it object.
private void Form1_Load(object sender, EventArgs e)
{
//Some other area where the datagridview is populated with more information
SqlConnection con = new SqlConnection(#"MyConnectionString");
con.Open();
SqlDataAdapter sda = new SqlDataAdapter("SELECT FirstName, LastName, Address, State FROM Employee", con);
dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
//all that should be needed to filter the datagridview to your condition
dt.DefaultView.RowFilter = string.Format("FirstName LIKE '%{0}%'", textBox1.Text);
}
Of course, you really need to switch to using statements so that the objects used are disposed of properly but this is to show more that the basic reason your grid is doing this is that you are applying another datasource into the grid and it doesn't know that you still want all the information you had prior just limited to rows that match your filter.
EDIT - FOR CLARIFICATION
Let's do this. In your loaddata code, remark out the entire for each loop. Add the following lines
datagridview1.columns.clear();
datagridview1.datasoure = dt;
This will hide your pre-existing columns for now without you having to do it manually.
And should show the grid with all the information from the query.
Then in your textchanged event remark all your code and replace it with the line I showed above that uses the DefaultView of the datatable (dt)
That should get you up and running. Once that's done, we can make a change to the query that will allow you to show 'Active'/'InActive' instead of the checkbox for the bit field.
private void fill()
{
adptr = new OleDbDataAdapter(#"SELECT * FROM LibraryInfo WHERE First_Name='"+LoginName+"'", cn);
//LoginName is a string variable for displaying users info after the login
ds.Clear();
adptr.Fill(ds);
dataGridView1.DataSource = "";
dataGridView1.DataSource = ds.Tables[0];
}
After the database updated, GridView didn't show data.
Taken from this msdn article on the DataBind Property.
ASP EXAMPLE
void Page_Load(Object sender, EventArgs e)
{
// This example uses Microsoft SQL Server and connects
// to the Northwind sample database. The data source needs
// to be bound to the GridView control only when the
// page is first loaded. Thereafter, the values are
// stored in view state.
if(!IsPostBack)
{
// Declare the query string.
String queryString =
"Select [CustomerID], [CompanyName], [Address], [City], [PostalCode], [Country] From [Customers]";
// Run the query and bind the resulting DataSet
// to the GridView control.
DataSet ds = GetData(queryString);
if (ds.Tables.Count > 0)
{
AuthorsGridView.DataSource = ds;
AuthorsGridView.DataBind();
}
else
{
Message.Text = "Unable to connect to the database.";
}
}
}
DataSet GetData(String queryString)
{
// Retrieve the connection string stored in the Web.config file.
String connectionString = ConfigurationManager.ConnectionStrings["NorthWindConnectionString"].ConnectionString;
DataSet ds = new DataSet();
try
{
// Connect to the database and run the query.
SqlConnection connection = new SqlConnection(connectionString);
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
// Fill the DataSet.
adapter.Fill(ds);
}
catch(Exception ex)
{
// The connection failed. Display an error message.
Message.Text = "Unable to connect to the database.";
}
return ds;
}
This snippet shows you how to (a) bind your dataset to a gridview, by assigning it using the Databind method.
The site also says:
Use the DataBind() method to bind data from a data source to the GridView control. This method resolves all data-binding expressions in the active template of the control.
SOLUTION
I would like to reference the line saying:
AuthorsGridView.DataBind();
which actually binds the data to the control.
SIDE NOTE
To protect yourself from SQLi, you should read up on SQL Parameters, and not direct concatenation.
WINFORM EXAMPLE
Tutorial was found: here
//create the connection string
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\myDatabase.mdb";
//create the database query
string query = "SELECT * FROM MyTable";
//create an OleDbDataAdapter to execute the query
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, connString);
//create a command builder
OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(dAdapter);
//create a DataTable to hold the query results
DataTable dTable = new DataTable();
//fill the DataTable
dAdapter.Fill(dTable);
Also:
//the DataGridView
DataGridView dgView = new DataGridView();
//BindingSource to sync DataTable and DataGridView
BindingSource bSource = new BindingSource();
//set the BindingSource DataSource
bSource.DataSource = dTable;
//set the DataGridView DataSource
dgView.DataSource = bSource;
Use are missing to call databind method here.Use following code :
DataAdapter adapter=new DataAdapter(SqlCommand,SqlConn);
DataTable tbl=new Datatable();
adapter.Fill(tbl);
GridView1.DataSource=tbl;
GridView1.DataBind();//This line is missing in your code
try with this format?
I am a newbie in C# so I don't know if I will address my problem correctly so please bear with me. I have 3 DataGridViews (datagridview1, datagridview2, datagridview3). All are located in the same window but they are in a different tab (I have a tab control).
The purpose of each DataGridView is to display data for three tables from database. So every time I click a button, it retrieves data. But here is my problem, when datagridview1 displays the data after clicking the button, then I go to the next tab and click again the retrieve button, the datagridview2 shows the data that was displayed to datagridview1. Same thing to datagridview3.
I'm using DataTable as the data source for those DataGridViews. And somewhere in my script the query will change so I think there's no problem with the query. What I found is that the DataTable does not clear it's data even when the query already changed.
I'm using WinForms, please help me. Thanks.
Here is the code I used in binding the datagridview to a datasource:
currentdatagrid.DataSource = execute.InitConn2(query, CompleteTablename);
Note: "execute.InitConn2(query, CompleteTablename)" will return a datatable.
Try doing something like the following example and see if it works for you. The static method GetData returns a new data table each time. You need to update the SqlConnection with your own connection string.
public static void Main(string[] args)
{
DataGrid dg1 = new DataGrid();
DataGrid dg2 = new DataGrid();
DataGrid dg3 = new DataGrid();
dg1.DataSource = GetData("select * from table1");
dg1.DataBind();
dg2.DataSource = GetData("select * from table2");
dg2.DataBind();
dg3.DataSource = GetData("select * from table3");
dg3.DataBind();
}
public static DataTable GetData(string sqlQuery) {
try
{
DataTable dt = new DataTable();
// set your connection here
SqlConnection conn = new SqlConnection("");
// execute query with your connection
SqlDataAdapter adapt = new SqlDataAdapter(sqlQuery, conn);
// open connection, fill data and close
conn.Open();
adapt.Fill(dt);
conn.Close();
return dt;
}
catch (Exception ex) {
throw ex;
}
}
To use a dataset use the following:
public static void Main(string[] args)
{
DataGrid dg1 = new DataGrid();
DataGrid dg2 = new DataGrid();
DataGrid dg3 = new DataGrid();
DataSet ds = GetData(#"select * from table1;
select * from table2;
select * from table3");
dg1.DataSource = ds.Tables[0];
dg1.DataBind();
dg2.DataSource = ds.Tables[1];
dg2.DataBind();
dg3.DataSource = ds.Tables[2];
dg3.DataBind();
}
public static DataSet GetData(string sqlQuery) {
try
{
DataSet ds = new DataSet();
// set your connection here
SqlConnection conn = new SqlConnection("");
// execute query with your connection
SqlDataAdapter adapt = new SqlDataAdapter(sqlQuery, conn);
// open connection, fill data and close
conn.Open();
adapt.Fill(ds);
conn.Close();
return ds;
}
catch (Exception ex) {
throw ex;
}
}
I currently have this code to populate ASP.NET gridview from code behind with DataTable.
protected void bindGridView()
{
SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString);
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = "SELECT id AS 'Member ID', name AS Name, age AS Age, sympton AS Sympton, phone AS Phone, nirc AS NIRC, address AS Address FROM tbl_customer_profile WHERE id = #id";
cmd.Parameters.AddWithValue("#id", txtSearchID.Text);
DataTable dtSearchResult = new DataTable();
SqlDataAdapter daSearchResult = new SqlDataAdapter();
try
{
sqlConn.Open();
daSearchResult.SelectCommand = cmd;
daSearchResult.Fill(dtSearchResult);
gridSearchResult.DataSource = dtSearchResult;
gridSearchResult.DataBind();
}
catch (SqlException ex)
{
lblStatus.Text = ex.Message;
}
finally
{
sqlConn.Close();
}
}
But I would lose the Grid's Selection, Sorting, Paging functions. So I was thinking if I could fill to SqlDataSource instead of Datatable and then bind to Gridview, I wouldn't have to handle the selection, sorting etc manually?
But I can't just simply do like daSearchResult.Fill(sqlDataSource1);
Is there any workaround?
Kind of like what Neeraj was saying you can bind directly to a gridview with an SqlDataSource.
You don't need to have all that plumbing code.
This is how in asp.net
<asp:GridView ID="grid" runat="server" DataSourceID="source"></asp:GridView>
<asp:SqlDataSource ID="source" runat="server"></asp:SqlDataSource>
This is how in C#
SqlDataSource source =new SqlDataSource();
GridView grid = new GridView();
grid.DataSource = s;
grid.DataBind();
I have some difficulty with the following: I have a dataset that I want to use to update the database when a change of value is made in the gridView. The dataset comes from the following method:
public static DataSet Display_all_members()
{
ds = new DataSet();
try
{
string query = "SELECT date_to, last_name ,first_name , member_pay FROM Member ";
conS.Open();
adapter = new SqlDataAdapter(query, conS);
adapter.Fill(ds, "To_display");
}
catch (Exception r)
{}
finally
{
conS.Close();
}
return ds;
}
In the form I do
ds2 = DAL.Display_all_members ();
dataGridView1.DataSource = ds2;
dataGridView1.DataMember = "To_display";
now I get to update and I do the following in the form
if (ds2.HasChanges() == true)
{
DAL.update(ds2);
}
In the method
public static void update(DataSet ki)
{
SqlCommandBuilder n = new SqlCommandBuilder(da);
da.Update(ds);
}
And it doesn’t work. What’s the problem?
This is the error: Update unable to find TableMapping['Table'] or DataTable 'Table'.
It might be just a typo, but your update method is using two different variables - DataSet ki, and da in the DataAdapter.Update() call.
Try this:
protected void update(DataSet ds)
{
da.Update(ds, 'To_display")
}
From DataAdapter DataTable and DataColumn Mappings (ADO.NET):
"If you do not specify a TableName or a DataTableMapping name when calling the Fill or Update method of the DataAdapter, the DataAdapter looks for a DataTableMapping named "Table". If that DataTableMapping does not exist, the TableName of the DataTable is "Table"."
If you're using the same DataSet that you originally filled, you'll probably want to keep specifying the table name where required to avoid this error.