I have a datagridview with a checkbox column. The checkbox cell should change the color and check status based on a specific value in the database table column. If that value is "grafcheck", then the checkbox cell and checkbox should be green and checked. If the field in the table is null, the checkbox cell should be white and unchecked. The below code does what it should but it marks as checked every checkbox and makes them all green regardless if the value is present or not.
using (SqlConnection con = new SqlConnection(@"Data Source=GAMEWORK\SQLEXPRESS;Initial Catalog=Tida;Integrated Security=True"));
{
DataGridViewCellStyle style = new DataGridViewCellStyle();
style.BackColor = Color.Green;
style.ForeColor = Color.White;
string sql = "SELECT GraficaFinal FROM Comenzi WHERE GraficaFinal='grafcheck'";
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
string graph = reader["GraficaFinal"].ToString();
for (int i = 0; i < ComNef.Rows.Count; i++)
{
if (graph == "grafcheck")
{
ComNef.Rows[i].Cells["chkbxGrafica"].Value = true;
ComNef.Rows[i].Cells["chkbxGrafica"].Style = style;
}
else if (graph == "")
{
ComNef.Rows[i].Cells["chkbxGrafica"].Value = false;
ComNef.Rows[i].Cells["chkbxGrafica"].Style.BackColor = Color.White;
}
}
}
}
con.Close();
}
You may want to re-think your approach here. First you say that after the code runs, all the check boxes are checked and green. And from what I can see this makes sense because the query is only getting the rows… … WHERE GraficaFinal='grafcheck'
… So if you are getting data back from the query… then ALL the rows will have grafcheck
. This pretty much makes the… if (graph == "grafcheck") {..
… statement superfluous.
Another issue…, the… while (reader.Read()) { …
… loop is iterating over the lines read, so the code reads a line, then sets the graph
variable like…
string graph = reader["GraficaFinal"].ToString();
this is fine… HOWEVER … the code then (for some unknown reason) “loops” through ALL the rows in the grid …? … this can not be right. Basically, is what will happen when using the for
loop through the rows of the grid will set each rows check box state to the “current” lines graph
value… regardless of what the actual value is in the GraficaFinal
cell on that row. However we already know it will be “grafcheck.”
If you trace this code it will basically set all the check box values and color to whatever the LAST row in the data contains. In other words… I am confident you do NOT want a for
loop there, you would ONLY be setting ONE (1) value in that row. And this brings up “why” is the code “manually” adding the values to the grid? I am confident you could use a DataTable
and get it filled directly from the query. Then you could simply use the DataTable
as a DataSource
to the grid. The code to fill the table may look something like…
DataTable GridDT = new DataTable(“Comenzi”);
GridDT.Load(reader);
This would fill the table with one column of GraficalFinal
data based upon the query you have.
Also… It is unclear “where” the chkbxGrafica
column in the ComNef
grid is coming from… I will assume you are adding the column in the designer or possibly in some code that is not shown. If you are adding the column manually to the GRID as it appears you are, then there is an easier approach.
Instead of manually adding the column to the GRID, I suggest you manually add the column to the DataTable
we previously got from the DB query. This may appear trivial as to whether you add the column to the GRID or TABLE… however, the GRID column does not have the ability to use an “Expression” in its column. The DataTable
allows for a column to contain an “expression”…
DataColumn.Expression Property
This will come in very handy where we want to set the chkbxGrafica
cell to a checked or not checked state. This expression may look something like…
"IIF(GraficalFinal = 'grafcheck', 'true', 'false')"
This will “automatically” set the check box cell to the proper check state. NOTE… because the check box column is an “expression” column… then the user will NOT be able to change the check box state directly, however… changing the GraficaFinal
cell WILL change the check box state. This simple one line of code for the “expression” column would eliminate all the code that loops through the grid and sets the check box values.
In addition… once the code is running and the user “changes” a GraficalFinal
cell value to any value other than grafcheck
… then… the check box on that row will automatically become “unchecked.” Obviously, if the cells value IS “grafcheck” then this will set the check box to “checked”
Unfortunately, this is NOT going to “color” the cell as you want. For this, we WILL need to look to the GRID. Ňɏssa Pøngjǣrdenlarp commented a link that is one of many possible ways to color the grid cells. The most common and intuitive grid event to change the cells color would be the grids CellFormatting
event. This event will fire when the cell needs to be formatted and in this event we could simply check to see what the check box value is and then color it appropriately.
A word of caution… using the grids CellFormatting
event for this works well, however, if you drop a Debug
statement into the event… you will note that the event will fire many more times than is needed. Example, it may fire when the user simply moves the cursor over the cells in the grid. This is one reason I may choose a different event like the grids CellValueChanged
event.
Unfortunately, this opens the door to more work since that event will NOT fire when grids DataSource
is set. The CellFormatting
event WILL fire when the grids DataSource
is set. So… if we used the grids CellValueChanged
event instead of the grids CellFormatting
event… then… we kind of end up in the same boat we are already in… we will need to implement addition code to “loop” through all the rows in the GRID and set the cell colors right after the grids DataSource
is set. Granted, this eliminates the cell getting formatted when it doesn't need it, however, it creates more work for you. In the example below… I will use the grids CellFormatting
event.
So… to sum up… add a Boolean type column with an “expression” to the DataTable
. This will set the check box values based upon what the GraficalFinal
cell contains. Then wire-up the grids CellFormatting
event to set the cells color.
A small yet complete example of what is described above is demonstrated in the code below. NOTE… obviously the GetDataFromDB
method simply creates a single column table with some random values and you would change this code to get the GraficaFinal
table from your DB. If you drop a DataGridView
onto a form and wire up its CellFormatting
event, then, below is what the code should produce. Good Luck.
DataTable GridDT;
DataGridViewCellStyle CheckedStyle;
DataGridViewCellStyle UnCheckedStyle;
public Form1() {
InitializeComponent();
CheckedStyle = new DataGridViewCellStyle();
UnCheckedStyle = new DataGridViewCellStyle();
CheckedStyle.BackColor = Color.Green;
CheckedStyle.ForeColor = Color.White;
UnCheckedStyle.BackColor = Color.White;
UnCheckedStyle.ForeColor = Color.Black;
}
private void Form1_Load(object sender, EventArgs e) {
GridDT = GetDatFromDB();
AddCheckBoxColumnToTable(GridDT);
dataGridView1.DataSource = GridDT;
}
private DataTable GetDatFromDB() {
DataTable dt = new DataTable();
dt.Columns.Add("GraficalFinal", typeof(string));
Random rand = new Random();
for (int i = 0; i < 10; i++) {
if (rand.Next(2) == 0) {
dt.Rows.Add("grafcheck");
}
else {
dt.Rows.Add("");
}
}
return dt;
}
private void AddCheckBoxColumnToTable(DataTable dt) {
DataColumn col = new DataColumn("chkBxGrafica", typeof(bool), "IIF(GraficalFinal = 'grafcheck', 'true', 'false')");
dt.Columns.Add(col);
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
if (e.ColumnIndex == 1) {
if (!dataGridView1.Rows[e.RowIndex].IsNewRow) {
//Debug.WriteLine("DGV_CellFormatting <- Enter");
if ((bool)dataGridView1.Rows[e.RowIndex].Cells[1].Value == true) {
dataGridView1.Rows[e.RowIndex].Cells[1].Style = CheckedStyle;
}
else {
dataGridView1.Rows[e.RowIndex].Cells[1].Style = UnCheckedStyle;
}
//Debug.WriteLine("DGV_CellFormatting -> Leave");
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.