populate DataGridView from database and TextBox - c#

Basically I want to add another column from a TextBox along with values I have queried from the database. I want my datagridview to show something like
|itemcode|Category|itemDescription|unitcost|quantity|
where itemcode, Category, itemDescription, unitcost is from database and quantity is from a text box input.
private void btnAddToCart_Click(object sender, EventArgs e)
{
con.OpenConnection();
MySqlCommand cmd = con.connection.CreateCommand();
string search = txtSearchProduct.Text;
string quantity = txtQuantity.Text;
string query = "SELECT itemcode, Category, itemDescription, unitcost FROM tblprowareproducts WHERE itemDescription LIKE ?search";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("?search", "%" + search + "%");
using (MySqlDataAdapter mda = new MySqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
mda.Fill(dt);
dgvCart.DataSource = dt;
}
}
Is there a way to add another column after unitcost named quantity and the value of it comes from a TextBox?

There are different solutions for the problem, for example you can add the column to DataTable this way:
DataTable dt = new DataTable();
mda.Fill(dt);
var quantity = dt.Columns.Add("quantity", typeof(int));
quantity.DefaultValue = int.Parse(txtQuantity.Text);
dt.AsEnumerable().ToList().ForEach(r =>
{
r[quantity] = quantity.DefaultValue;
});
dgvCart.DataSource = dt;
Note 1: You may want to use TryParse to get the integer value from text.
Note 2: Default value of column applies to the column when adding the row. So to apply it to existing rows, you need to use a loop like what I did. For new rows that you add after that, it will be applied automatically.

Related

C# - How to fill an existing DataGridView with data from an Access Database

I am working on a Tool Crib system. I need to have a way to fill my dataGridView with past Purchase Orders.PO List on the left side to fill DataGridView. I have used this before to fill gridViews:
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
string orderNumber = lbOrders.SelectedItem.ToString();
string query = "SELECT PartNumber from PurchaseOrders WHERE PONumber LIKE '%" + orderNumber + "%' ";
cmd.CommandText = query;
//OleDbDataReader reader = cmd.ExecuteReader();
cmd.ExecuteNonQuery();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
However I don't know how to fill an existing dataGridView table. As in I don't know how to use the columns that I already have to create Purchase Orders. The da.Fill(dt) just adds all new columns and I end up with and extra column and a lot of empty cells.
Extra Column for PartNumber
I tried to just fill the Item column with this code:
string query = "SELECT PartNumber from PurchaseOrders WHERE PONumber LIKE '%" + orderNumber + "%' ";
cmd.CommandText = query;
OleDbDataReader reader = cmd.ExecuteReader();
//cmd.ExecuteNonQuery(); //not using this code
//OleDbDataAdapter da = new OleDbDataAdapter(cmd); //not using this code
//DataTable dt = new DataTable(); //not using this code
//da.Fill(dt); //not using this code
//dataGridView1.DataSource = dt; //not using this code
List<string> result = new List<string>();
for (int i = 0; i < result.Count - 1; i++)
while (reader.Read())
{
result.Add(reader.GetString(0));
//dataGridView1.Rows[0].Cells["Item"].Value = (reader["PartNumber"]).ToString(); //not using this code
}
for (int i = 0; i < result.Count-1; i++)
{
foreach (var item in result)
{
dataGridView1.Rows[i].Cells["Item"].Value = result[i];
}
}
con.Close();
This code sort of worked for me. However, it kept saying that my index was out of range and would never fill the "Item" column correctly/completely. The other downside to this is that I still needed to bring in the Quantity. I have the grid bring in the other information when there is a change to a cell value. It looks at the database of items to get description and price, so all I need to do is to be able to fill the Item and quantity columns.
I've been at this for a few hours now and I need help.
Summary: I need a way to fill my Item, and Quantity columns with part numbers and quantities stored in an Access DataBase - DB Columns are [PO#, PartNumber, Quantity]
Sorry if this seems like a lot / not enough information. I just need help.

Implement value from datatable into datagridview

I'm trying to change the color of 3 cells based on the corresponding database value attached to the physician initials. In other words, the physician has a specific color for the cell background when they view their patients. The database "physicians" has three columns (Physician Name, Initials, Color). Below is some of the code.
void PhysicianColorTreatPrep()
{
string ColorQuery = "SELECT * FROM physicians";
SqlConnection connectionstring = new SqlConnection(constring);
connectionstring.Open();
DataTable dsDocColor = new DataTable();
SqlDataAdapter adapterDocColor = new SqlDataAdapter(ColorQuery, constring);
adapterDocColor.Fill(dsDocColor);
foreach (DataGridViewRow row in datagridviewTreatmentPrep.Rows)
{
DataRow[] result = dsDocColor.Select("Color WHERE Initials = "+row.Cells["Primary_Onc"].Value.ToString()+"");
row.Cells["Last_Name"].Style.BackColor = //Color retrieved from datatable based on datagridview value
row.Cells["First_Name"].Style.BackColor = //Color retrieved from datatable based on datagridview value
row.Cells["Primary_Onc"].Style.BackColor = //Color retrieved from datatable based on datagridview value
}
}
#ChetanRanpariya Thanks for asking the right questions. I managed to solve it. Below is the code.
DataRow[] result = dsDocColor.Select("Initials = '"+row.Cells["Primary_Onc"].Value.ToString()+"'");
string DocColor = result[0][2].ToString();
row.Cells["Last_Name"].Style.BackColor = System.Drawing.Color.FromName(DocColor);
row.Cells["First_Name"].Style.BackColor = System.Drawing.Color.FromName(DocColor);
row.Cells["Primary_Onc"].Style.BackColor = System.Drawing.Color.FromName(DocColor);

How to create a datagridview from another one?

I use visual studio 2012: c# winform. I have a datagridview in which 2 columns(Id and society) are created. the datagridview contains 25 records fetched my database.
I also added a button named "Action" to each row in datagridview
Note: In my phpmyadmin database, each society contains many service category and service types
My problem is:
I want that when a button "action" is pressed, all the service category and service type related to that society appear in the same or another datagridview.
Could you help me?
Try somthing like that, you must initiate this function with your main DataGridView, and you will have your "Cloned" DataGridView.
public DataGridView CloneDataGrid(DataGridView mainDataGridView)
{
DataGridView cloneDataGridView = new DataGridView();
if (cloneDataGridView.Columns.Count == 0)
{
foreach (DataGridViewColumn datagrid in mainDataGridView.Columns)
{
cloneDataGridView.Columns.Add(datagrid.Clone() as DataGridViewColumn);
}
}
DataGridViewRow dataRow = new DataGridViewRow();
for (int i = 0; i < mainDataGridView.Rows.Count; i++)
{
dataRow = (DataGridViewRow)mainDataGridView.Rows[i].Clone();
int Index = 0;
foreach (DataGridViewCell cell in mainDataGridView.Rows[i].Cells)
{
dataRow.Cells[Index].Value = cell.Value;
Index++;
}
cloneDataGridView.Rows.Add(dataRow);
}
cloneDataGridView.AllowUserToAddRows = false;
cloneDataGridView.Refresh();
return cloneDataGridView;
}
Hope This Help
If i understand your question correctly, you could use a cell content click event to refill your datatable with the filtered results.
I've done this on one of my forms (see below), however I havent used a phpmyadmin database, only sql, but the logic might be the same.
I should also note that I have the default cell selection as full row select.
For arguments sake, let's say the form shows products, so ProductID, ProductName and ProductType. When we click the button in the grid we want it to filter by the selected row's ProductType.
//First we declare a static string that can be accessed by the whole form
//and blank it so the form doesnt use a previous value.
public static string product_type = ""
//In the form load event, the gridview is populated - this could be moved to anywhere.
private void Form1_Load(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection("DB connection string");
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM Products", conn);
SqlDataAdapter sqlDataAdap = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
sqlDataAdap.Fill(ds);
DataTable dt = new DataTable();
sqlDataAdap.Fill(dt);
conn.Close();
}
//In the cell contect click event we give it the ProductType
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
//Here we declare a var to identify that we're looking at the row
var row = dataGridView1.CurrentRow.Cells;
//Now we set the string we declared earlier
product_type = Convert.ToString(row["ProductType"].Value);
//Now we repeat the grid script with a parameter which uses our string from above
SqlConnection conn = new SqlConnection("DB connection string");
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM Products WHERE ProductType = #ProductType", conn);
sc.Parameters.Add("#ProductType", SqlDbType.Int).Value = product_type;
SqlDataAdapter sqlDataAdap = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
sqlDataAdap.Fill(ds);
DataTable dt = new DataTable();
sqlDataAdap.Fill(dt);
conn.Close();
}
You could then just add a button which repeats the script from the form load event when clicked to return the grid to it's non-filtered state.
Hope this helps.

how to retrieve the value of the input query textbox in C# asp.net?

example I have a textbox input, the contents of the input textbox custom query of the user what the user inputted, an example in the textbox, I try to enter text "select id, name, country from the country" .. from the sql query on the results of the 3 coloumn of the country table, I asked how to take the number of columns, the column name of the textbox custom input .. to the number of columns I want to show in the textbox and the number of rows in the gridview appropriate number of columns in a query, for the names of the columns I want to display in gridview ..
private void BindReportColumn(String report_id)
{
dt = mda.GetData("SELECT column_name,column_text,size,back_color,fore_color FROM report_column INNER JOIN report ON report_column.report_id = report.report_id and report.report_id='" + report_id + "'", connStr).Tables[0];
GridCustomColumn.DataSource = dt;
GridCustomColumn.DataBind();
}
private void addcolumn()
{
int i;
//Add the items to the gridview
DataTable dt = new DataTable();
//Assign the viewstate to the datatable
if (!IsNumeric(txtcolumn_count.Text)) txtcolumn_count.Text = "0";
dt = (DataTable)ViewState["columnreport"];
for (i = 1; i <= Convert.ToInt32(txtcolumn_count.Text); i++)
{
DataRow dr = dt.NewRow();
//dr["report_id"] = txtreport_id.Text;
dr["column_name"] = "";
dr["column_text"] = " ";
dr["size"] = 0;
dr["back_color"] = "";
dr["fore_color"] = "";
//Add the datarow to the datatable
dt.Rows.Add(dr);
//Now bind the datatable to the gridview
GridCustomColumn.DataSource = dt;
GridCustomColumn.DataBind();
//Add the details to viewstate also
ViewState["columnreport"] = dt;
}
}
thanks in advance

DataView RowFilter doesn't filter the Rows on DataGridView

I have this function button_Search1_Click to search for comments that match keywords, then display these flagged comments in dataGridView_flaggedComments.
Next, if there's any changes on the comboBox_stockIndex, I want the filter to take place i.e. filter the flagged comments in dataGridView_flaggedComments with the Tickers_Ticker_ID of 1. But when I do that, all the comments (regardless flagged or not) belong to Tickers_Ticker_ID of 1 display on my dataGridView_flaggedComments. It should have only display the flagged comments for Tickers_Ticker_ID of 1, not all the comments.
I think there's something wrong with the DataSource but I couldn't figure it out. Any help would be very very much appreciated! Thank you!
(If I did miss any similar questions, kindly point it out. Thank you very much!)
private void button_Search1_Click(object sender, EventArgs e)
{
commentCount = 0;
richTextBox_flaggedComments.Clear();
dataGridView_flaggedComments.Refresh();
DataTable flaggedcomments = new DataTable("flaggedcomments");
using (MySqlConnection sqlConn = new MySqlConnection(strProvider))
{
using (MySqlDataAdapter da = new MySqlDataAdapter(
"SELECT Comment_ID, Comments_Date, Author, Title, Comments_Comment, " +
" Tickers_Ticker_ID FROM comments ORDER BY Comments_Date ASC", sqlConn))
{
da.Fill(flaggedcomments);
}
}
StringBuilder sb = new StringBuilder();
string[] words = File.ReadAllLines(sourceDirTemp +
comboBox_crimeKeywords.SelectedItem.ToString() + ".txt");
var query = flaggedcomments.AsEnumerable().Where(r =>
words.Any(wordOrPhrase => Regex.IsMatch(r.Field<string>("Comments_Comment"),
#"\b" + Regex.Escape(wordOrPhrase) + #"\b", RegexOptions.IgnoreCase)));
dataGridView_flaggedComments.DataSource = query.AsDataView();
}
private void comboBox_stockIndex_SelectedIndexChanged(object sender, EventArgs e)
{
DataView dv = dataGridView_flaggedComments.DataSource as DataView;
if (dv == null)
throw new Exception("Bad Data Source type");
else
{
dv.RowFilter = string.Format("Tickers_Ticker_ID = '1'");
dataGridView_flaggedComments.DataSource = dv;
}
}
A DataView as such does not hold any data.
When you set the filter you are effectively replacing the orginal filter in your LinqDataView, that is the Where clause, by the new filter, that is by the RowFilter.
You need to concatenate them to create a double condition.
Since your Where clause uses a complex RegEx I think the easiest way will be to re-use it, appending it with the new, simple 'Tickers_Ticker_ID = ' + id condition.
If you don't want to reapply the original filter you may want to store the filtered rows in a temporary Table. Here I have a DataSet DS and first clone the structure of the 1st Table, name the new Table and add it to the DataSet. When appropriate I copy the filtered rows over from the query:
Set up the Temp Table, where you set up you other DB stuff:
DataSet DS; // if you don't already have one..
// put it at class level!
DS = new DataSet(); // ..create it
DataTable DT = DS.Tables[0].Clone(); // the temp table has the sdame structure
DT.TableName = "temp"; // is called by a name
DS.Tables.Add(DT); // and (optionally) added to the DataSet.
When you do the search you load the data into the temp table:
DS.Tables["temp"].Rows.Clear();
query.CopyToDataTable( DS.Tables["temp"], LoadOption.OverwriteChanges);
DGV.DataSource = DS.Tables["temp"];
Now you can use it in the combo_filter_SelectedIndexChanged event:
string id = ddl_filter.Text;
if (id == "") DGV.DataSource = DS.Tables["temp"];
else
{
DataView dv = new DataView(DS.Tables["temp"])
dv.RowFilter = string.Format("id = " + id) ;
DGV.DataSource = dv;
}
Your filtering wrong... try this instead...
dv.RowFilter = "Tickers_Ticker_ID = 1";

Categories

Resources