USe Values from Gridview - c#

I am using a web form to pull data from a sql database, populate a datatable and use that datatable to populate a Gridview.
The code for populating the GridView when the search button is pressed
executes a Sql Query then sets the data Source to the datatable (GT1)
GT1.Load(SCDR);
EntryGrid.ShowHeaderWhenEmpty = true;
EntryGrid.DataSource = GT1;
EntryGrid.DataBind();
EntryGrid.EditIndex = 0;
EntryGrid.DataBind();
I was originally going to just use the gridview to populate a series of variables and use those to generate a Sql query, but EntryGrid.Rows[0].Cells[2].Text produces an empty string.
row.Cells[4].Text returns nothing in GridView1_SelectedIndexChanged? talks about using FindControl("control ID") , but I just got more confused looking at this. how do I find the control ID, and what exactly would I need to do to take a value from a specific cell in the gridview to a string variable?
The gridview is populated by the following code
DataTable GT1 = new DataTable();
protected void Button1_Click(object sender, EventArgs e)
{
string SqlQuery1 = sql.Replace("LASTNAME_", LastnameBox.Text);
SqlQuery1 = SqlQuery1.Replace("LAST4_", PAsswordBox.Text);
SqlConnection Conn1 = new SqlConnection(DC1.DbConn);
Conn1.Open();
SqlCommand SearchCommand = new SqlCommand(SqlQuery1, Conn1);
SqlDataReader SCDR = SearchCommand.ExecuteReader();
GT1.Load(SCDR);
EntryGrid.ShowHeaderWhenEmpty = true;
EntryGrid.DataSource = GT1;
EntryGrid.DataBind();
EntryGrid.EditIndex = 0;
EntryGrid.DataBind();
}

The Control ID is the Id you set for your each of your items in the TemplateField. Here is an example of using the FindControl to get the information from a label and storing it in VarFromGrid. The row is grab by RowSelected. Not sure how you are wanting to get the row but that is one way to do it.
aspx code:
<asp:Label ID="LabelGridViewBankName" runat="server" Text="something"></asp:Label>
code behind:
GridViewRow row = GridView1.SelectedRow;
string VarFromGrid = row.Cells[4].FindControl('LabelGridViewBankName').Text;
EDIT:
You can use a GridViewRow to grab the row, then grab the data from it like below. You shouldn't need the find control.
GridViewRow row = (GridViewRow)EntryGrid.SelectedItems[0];
string something = row.Cells[0].Text;
Just remember to make sure the Grid row is not null or you'll get a null exception. And to close your connection string once done. I this still returns an empty string, take a look at your dataTable in debug mode and see how the data is being stored.

Related

Problem with format in C# with DataGridView and TextBox

I have a problem with format in C#.
I have a DataGridView and a TextBox. In this datagridview, there is a column: the single price (format int).
I want sum every elements of single price's column and insert the result into this textbox, but Visual Studio gives me a problem with format of string input ("Format of input's string is not correct").
this is the code than i used:
int TOT = 0;
for (int i = 0; i < dataGridView3.Rows.Count; i++)
{
TOT = TOT + Convert.ToInt32(dataGridView3.Rows[i].Cells[6].ToString());
}
textBoxTot.Text = Convert.ToString(TOT);
Can you help me with this bad error?
UPDATE:
I think that the problem now is another. I can't find the methods of MySql.Data.MySqlClient library that it can give me the result of query.
MySqlCommand command = new MySqlCommand();
String sumQuery = "SELECT SUM(`prezzo`) FROM `fatturetemp`";
command.CommandText = sumQuery;
command.Connection = conn.getConnection();
command.Parameters.Add("#prezzo", MySqlDbType.Int32).Value = costo;
conn.openConnection();
conn.closeConnection();
How is the command that give me the result of sumQuery. If i find this command, i can take the result of query and paste in textbox
If your datagridview is showing a datatable (I.e. your data is stored in a datatable) you can add a DataColumn to the datatable whose .Expression property is set to the string "SUM([Price])", where Price is the name of your numeric datatyped column holding the price info.
Now every row in the table will have the sum of the prices (the same value over and over again), so if you want to databind your textBox to this new column then it will always show the sum no matter which row is the current row (because all rows have the same value). It will also auto update without you having to do anything!
And if you're not using databinding to a datatable, I recommend that you do do it, because it represents good MVC practice of keeping your data in one thing (DataTable) and showing it in another (DataGridView) and keeping these concerns separate
It would look something like this, as a quick example:
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Price", typeof(int));
dt.Columns.Add("CalculatedTotal", typeof(int)).Expression = "SUM([Price])";
dt.Rows.Add("Apples", 100);
dt.Rows.Add("Oranges", 200);
BindingSource bs = new BindingSource();
bs.DataSource = dt;
WhateverDataGridView.DataSource = bs;
totalTextBox.DataBindings.Add(new Binding("Text", bs, "CalculatedTotal", true));
Here we have a data model (the datatable) where we keep our data. It has a couple of things we can set directly, and an third column that calculates based on the existing prices in all the table. If you look at this in the datagridview (assuming you have autogeneratecolumns turned on) you'll see that both rows have 300 for the CalculatedTotal, but they have individual amounts for price. There is a device called a BindingSource that sits between the datatable and the UI controls; you don't have to have one but it makes certain things easier regards updating controls when the data changes, and it maintains a concept of "current" - essentially whatever the current row is you're looking at in the datagridview; it all helps to avoid having to ask the DGV for anything - we just let the user type into the DGV, and it shows the data out of the datatable. All our dealings can be with the datatable directly - if you wrote a button to loop through the table and double all the prices, the controls in the UI would just reflect the change automatically. The textbox is connected to the CalculatedValue column via databinding; whatever the current row is, the textbox will show the CalculatedValue. Because the CalculatedValue column has the same value on every row, and they always all update if any price changes, the total textbox will always show the total. Add another textbox bound to Name to see what I mean; as you click around the grid and select different rows to be the "Current" row, the Name will change but the total does not. In truth it is actually changing in the same way that Name is, it's just that because the actual numeric value is the same on every row the contents of the textbox look like they don't change
UPDATE: I think that the problem now is another. I can't find the methods of MySql.Data.MySqlClient library that it can give me the result of query.
public string sommaFattura(String costo)
{
MySqlCommand command = new MySqlCommand();
String sumQuery = "SELECT SUM(`prezzo`) FROM `fatturetemp`";
command.CommandText = sumQuery;
command.Connection = conn.getConnection();
command.Parameters.Add("#prezzo", MySqlDbType.Int32).Value = costo;
conn.openConnection();
conn.closeConnection();
}
How is the command that give me the result of sumQuery. If i find this command, i can take the result of query and paste in textbox
It is weird that you are first converting to a string and then to an int.
int TOT = 0;
for (int i = 0; i < dataGridView3.Rows.Count; i++)
{
if (!dataGridView3.Rows[i].IsNewRow &&
int.TryParse(dataGridView3.Rows[i].Cells[6].Value.ToString(), out int v))
TOT += v;
}
textBoxTot.Text = TOT.ToString();
EDIT: Edited for your updated question. You shouldn't ask question inside a question buy anyway:
string sumQuery = "SELECT SUM(`prezzo`) FROM `fatturetemp`";
decimal total = 0M;
using (MySqlConnection cn = new MySqlConnection(" your connection string here "))
using (MySqlCommand cmd = new MySqlCommand(sumQuery, cn))
{
cn.Open();
total = Convert.ToDecimal(cmd.ExecuteScalar());
cn.Close();
}
Console.WriteLine(total);

c# combobox DisplayMember showing empty rows from datatable

I have a multi column datatable like this,
datatable
I'm loading it to a combobox.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
datatable osdat = Loaddatatable();
postOScomboBox2.DataSource = osdat;
postOScomboBox2.DisplayMember = "Product";
postOScomboBox2.ValueMember = "Product";
postOScomboBox2.SelectedIndex = -1;
}
Instead of just showing p1,p2 the combobox is also showing two extra empty rows.
Same happens if i load the p1 column, 1 empty row is shown in combobox. Does display member have any property to check empty values and load only filled ones or any other way to achieve the same?
You can filter your table using methods from System.Linq.
datatable osdat = Loaddatatable();
var filteredTable = osdat.AsEnumerable()
.Where(row => row.Field<String>("Product") != null).CopyToDataTable();
postOScomboBox2.DataSource = filteredTable;
postOScomboBox2.DisplayMember = "Product";
postOScomboBox2.ValueMember = "Product";
postOScomboBox2.SelectedIndex = -1;
You have two empty values in product column and one empty value in p1 column. Combobox works as expected. If you want to filter these values filter your datasource instead. it's not a responsibility of combobox to filter datasource.
Here is a link how to filter datatable from empty values:
Filtering a empty string in DataTable

ComboBox Index Changed

Need to know: I am working with Windows Forms in Visual Studio and C#.
I have 5 comobobox's that I populate from SQL with the parts available in the DB. Part of the coding to it, one uses a DataTable and set the DataSource of the comboBox to that DataTable.
In this same DataTable via my SQL query, I have listed the cost of the part in the list. What I want to do is whichever part you pick from the dropdown list, the related price must show in the textbox next to it.
I am trying to use the comboBox1_SelectedIndexChanged for this, but the problem I run into is as soon as the DataSource gets set to the DataTable while the form's initial loading, it gets picked up as a Index change and the comboBox1_SelectedIndexChanged wants to run. But at this point in time, the SelectedIndex Value is null due to it still loading, causing it to give me a exception cast error.
how can I work around this?
DataTable SparePart = new DataTable() is declared outside the function to make it available as "public" so that the comboBox1_SelectedIndexChanged can access it.
Then I have this code to populate the comboBox:
//Read Status info from DB
SqlDataAdapter SparePartReader = new SqlDataAdapter(SQLSparePartDropbox);
SparePartReader.Fill(SparePart);
comboBoxFinJCSpares1.DataSource = SparePart;
comboBoxFinJCSpares1.DisplayMember = "DisplayMember";
comboBoxFinJCSpares1.ValueMember = "PartID";
//Set Combox1 affiliated Cost value to cost textbox
int ComBo1PartID = (int)comboBoxFinJCSpares1.SelectedValue;
string CostPrice = (from DataRow dr in SparePart.Rows
where (int)dr["PartID"] == ComBo1PartID
select (string)dr["PartCost"]).FirstOrDefault();
textBoxFinJCCost1.Text = CostPrice.ToString();
and then I have this for the comboBoxFinJCSpares1_SelectedIndexChanged:
//Set Combox1 affiliated Cost value to cost textbox
int ComBo1PartID = (int)comboBoxFinJCSpares1.SelectedValue;
string CostPrice = (from DataRow dr in SparePart.Rows
where (int)dr["PartID"] == ComBo1PartID
select (string)dr["PartCost"]).FirstOrDefault();
textBoxFinJCCost1.Text = CostPrice.ToString();
enter image description here
The solution is as easy as making one boolean variable and call it formLoaded.
Set it to false, then set it to true after the form loads.
Put your code for populating combobox inside if statement and that should do it
Cheers ~ ChenChi
demo:
//Read Status info from DB
if(formLoaded)
{
SqlDataAdapter SparePartReader = new SqlDataAdapter(SQLSparePartDropbox);
SparePartReader.Fill(SparePart);
comboBoxFinJCSpares1.DataSource = SparePart;
comboBoxFinJCSpares1.DisplayMember = "DisplayMember";
comboBoxFinJCSpares1.ValueMember = "PartID";
//Set Combox1 affiliated Cost value to cost textbox
int ComBo1PartID = (int)comboBoxFinJCSpares1.SelectedValue;
string CostPrice = (from DataRow dr in SparePart.Rows
where (int)dr["PartID"] == ComBo1PartID
select (string)dr["PartCost"]).FirstOrDefault();
textBoxFinJCCost1.Text = CostPrice.ToString();
}
Thanks guys, the "SelectedChangeCommitted" option suggested by Marcel Hoekstra solved my problem.

C# DatagridView search/filter

I am new to c#, I am trying to use filter the datagridview based on combobox value. Initially I loaded datagridview with all the desired values from database, now I want whenever user selects anything from combobox, the values in DataGridView should also change. One Solution which works for me is to request the database on each combobox value change and it works... code is attached for that
DataRowView view = (DataRowView)comboBox2.SelectedItem;
int year = (int) view.Row["Year"];
DataTable dt = new DataTable();
if (this.OpenConnection() == true)
{
String query = "Select * from yearly where year = "+year;
MySqlCommand cmd = new MySqlCommand(query, connection);
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
but, is there any way to not request the database again and again ? and I can filter the datagridview based on combobox value. Any tutorial or link will work.
In combobox's SelectionChangeCommitted event:
private void comboBox1_SelectionChangeCommitted(object sender, EventArgs e)
{
(dataGridView1.DataSource as DataTable).DefaultView.RowFilter = string.Format("Year= '{0}'", comboBox1.SelectedItem.ToString());
}
Hope it helps.
Solution 1:
If your data is changing frequently and you want up to date data you are OK to use the same code as yours.
Solution 2:
Get the data from datasource - Store into DataTable - Filter the data as per requirement and set DataGridView source to dataset.
You can also refer this

Drop Down List not getting populated

I have a c# code line as,
using (SqlDataSource sqlds = new SqlDataSource(ConnectionString(), SelectCommand()))
{
drop1.DataSource = sqlds;
drop1.DataTextField = "UserName";
drop1.DataBind();
}
now it's not populating my dropdownlist,
<asp:DropDownList id="drop1" runat="server" />
so I want to check if sql is returning data or not
if i put line break, I am not sure how to find out if sql is returning data, I am using using select statement and connection string for gridview and it works but not with drop down list
Be sure you have your sqlquery into select command then you need convert you
sqldatasource select command into dataview.
string query = "select yourfield from yourtable";
using (SqlDataSource sqlds = new SqlDataSource(conn.ConnectionString, query))
{
System.Data.DataView dv = (System.Data.DataView)sqlds.Select(DataSourceSelectArguments.Empty);
if (dv.Count > 0)
{
DropDownList1.DataSource = sqlds;
DropDownList1.DataTextField = "yourfield";
DropDownList1.DataBind();
}
}
You should be able to put a breakpoint on drop1.DataSource = sqlds; and then move your mouse over sqlds and it should show you how many rows are contained in the DataSource.
your way of binding datasource to the dropdown is correct and same thing is working for me.
Possible errors can be
in the connectionString. Verify if it is correct.
in the Select Query. Verify if the SelectCommand() methods returns correct sql query.
use Selected event of the SqlDataSource to verify whether it returned any row i.e
sqlds.Selected += new SqlDataSourceStatusEventHandler(sdl_Selected);
where sql_Selected is:
void sdl_Selected(object sender, SqlDataSourceStatusEventArgs e)
{
var a = e.AffectedRows;
}
as a Side note - make sure your select query doesn't contain any string concatenation prone to sql injection. i.e. SELECT UserName from [TableName] where certainCol ="+ variable.
Don't do it
provide a sql parameter instead, and add the SelectParameters to your SqlDataSource

Categories