[英]Changing datagridview cell color based on condition
我已將數據從數據庫加載到 datagridview 並有兩列目標值和體積,其中體積 > 目標值,體積單元格應為綠色,體積 < 目標值,然后體積應為紅色。 我試過了,但我做不到。
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
if (dataGridView1.Rows.Count > 0 && dataGridView1.Columns.Count > 0)
{
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (Volume > target value)
{
cell.Style.BackColor = Color.AliceBlue;
}
我可能建議不要在每次調用 CellFormating 時循環遍歷每一行,因為每次需要刷新 A SINGLE ROW 時都會調用它。
Private Sub dgv_DisplayData_Vertical_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles dgv_DisplayData_Vertical.CellFormatting
Try
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "6" Then
e.CellStyle.BackColor = Color.DimGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "5" Then
e.CellStyle.BackColor = Color.DarkSlateGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "4" Then
e.CellStyle.BackColor = Color.SlateGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "3" Then
e.CellStyle.BackColor = Color.LightGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "0" Then
e.CellStyle.BackColor = Color.White
End If
Catch ex As Exception
End Try
End Sub
你需要這樣做
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
foreach (DataGridViewRow Myrow in dataGridView1.Rows)
{ //Here 2 cell is target value and 1 cell is Volume
if (Convert.ToInt32(Myrow .Cells[2].Value)<Convert.ToInt32(Myrow .Cells[1].Value))// Or your condition
{
Myrow .DefaultCellStyle.BackColor = Color.Red;
}
else
{
Myrow .DefaultCellStyle.BackColor = Color.Green;
}
}
}
同時也看看單元格格式
Kyle 和 Simon 的回答是對 CPU 資源的嚴重浪費。 CellFormatting
和CellPainting
事件發生的次數太多,不應用於應用樣式。 這里有兩種更好的方法:
如果您的 DataGridView 或至少決定單元格樣式的列是只讀的,您應該在RowsAdded
事件中更改行的 DefaultCellStyle。 此事件僅在添加新行時發生一次。 應在那時評估條件,並應在其中設置行的DefaultCellStyle
。 請注意,此事件也會在 DataBound 情況下發生。
如果您的 DataGridView 或那些列允許編輯,您應該使用CellEndEdit
或CommitEdit
事件來更改DefaultCellStyle
。
foreach (DataGridViewRow row in dgvWebData.Rows)
{
if (Convert.ToString(row.Cells["IssuerName"].Value) != Convert.ToString(row.Cells["SearchTermUsed"].Value))
{
row.DefaultCellStyle.BackColor = Color.Yellow;
}
else
{
row.DefaultCellStyle.BackColor = Color.White;
}
}
這對我來說非常有用。 即使更改了一行,也會處理相同的事件。
假設您必須通過了解兩件事來為某些單元格(不是該行的所有單元格)着色:
在這種情況下,您必須使用事件CellFormatting
在我的情況下,我像這樣使用
private void DgvTrucksMaster_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
foreach (DataGridViewRow row in dgvTrucksMaster.Rows)
{
if (Convert.ToInt32(row.Cells["Decade1Hours"].Value) > 0)
{
row.Cells["Decade1Hours"].Style.BackColor = Color.LightGreen;
}
else if (Convert.ToInt32(row.Cells["Decade1Hours"].Value) < 0)
{
// row.DefaultCellStyle.BackColor = Color.LightSalmon; // Use it in order to colorize all cells of the row
row.Cells["Decade1Hours"].Style.BackColor = Color.LightSalmon;
}
}
}
結果你可以在這里看到
因此,在這里您可以通過名稱 row.Cells["Decade1Hours"] 訪問列中行的某些單元格
你怎么知道這個名字的? 那么在我的情況下,我像這樣創建 DataGridView 列。
var Decade1Hours = new DataGridViewTextBoxColumn()
{
Name = "Decade1Hours",
Width = 50,
DataPropertyName = "Decade1Hours",
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle()
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
ForeColor = System.Drawing.Color.Black,
Font = new Font(font, FontStyle.Bold),
Format = "n2"
},
HeaderCell = new DataGridViewColumnHeaderCell()
{
Style = new DataGridViewCellStyle()
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = System.Drawing.Color.Blue
}
}
};
Decade1Hours.HeaderText = "Дек.1";
dgvTrucksMaster.Columns.Add(Decade1Hours);
嗯……你需要例如為行中的一些單元格着色,比如 ##1 4 5 和 8 你必須使用單元格索引(它從 0 開始)。
代碼看起來像
private void DgvTrucksMaster_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
foreach (DataGridViewRow row in dgvTrucksMaster.Rows)
{
if (Convert.ToInt32(row.Cells[1].Value) > 0 )
{
row.Cells[1].Style.BackColor = Color.LightGreen;
}
}
}
沒有循環它可以像下面那樣實現。
private void dgEvents_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
FormatRow(dgEvents.Rows[e.RowIndex]);
}
private void FormatRow(DataGridViewRow myrow)
{
try
{
if (Convert.ToString(myrow.Cells["LevelDisplayName"].Value) == "Error")
{
myrow.DefaultCellStyle.BackColor = Color.Red;
}
else if (Convert.ToString(myrow.Cells["LevelDisplayName"].Value) == "Warning")
{
myrow.DefaultCellStyle.BackColor = Color.Yellow;
}
else if (Convert.ToString(myrow.Cells["LevelDisplayName"].Value) == "Information")
{
myrow.DefaultCellStyle.BackColor = Color.LightGreen;
}
}
catch (Exception exception)
{
onLogs?.Invoke(exception.Message, EventArgs.Empty);
}
}
private void dataGridView1_DataBindingComplete(object sender DataGridViewBindingCompleteEventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (Convert.ToInt32(row.Cells["balaceAmount"].Value) == 0)
{
row.DefaultCellStyle.BackColor = Color.Yellow;
}
else
{
row.DefaultCellStyle.BackColor = Color.White;
}
}
}
private void dataMain_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (dataMain.Columns[e.ColumnIndex].Name == "colStatus")
{
if (int.Parse(e.Value.ToString()) == 2)
{
dataMain.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.OrangeRed;
dataMain.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.White;
}
}
}
令人驚訝的是,沒有人提到一個簡單的if
語句可以確保您的循環只在每種格式中執行一次(在第一行的第一列上)。
private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
// once per format
if (e.ColumnIndex == 0 && e.RowIndex == 0)
{
foreach (DataGridViewRow row in dgv.Rows)
if (row != null)
row.DefaultCellStyle.BackColor = Color.Red;
}
}
我知道這是一個舊帖子,但我在 2018 年找到了我的方式,所以也許其他人也會這樣做。 在我看來,OP 有比提供的任何答案更好的方法(使用 dgv_DataBindingComplete 事件)。 在撰寫本文時,所有答案都是使用繪制事件或單元格格式事件編寫的,這似乎效率低下。
OP 完成了 99% 的工作,他們所要做的就是遍歷他們的行,測試每一行的單元格值,並設置 BackColor、ForeColor 或您想要設置的任何其他屬性。
請原諒 vb.NET 語法,但我認為它與 C# 足夠接近,應該很清楚。
Private Sub dgvFinancialResults_DataBindingComplete Handles dgvFinancialResults.DataBindingComplete
Try
Logging.TraceIt()
For Each row As DataGridViewRow in dgvFinancialResults.Rows
Dim invoicePricePercentChange = CSng(row.Cells("Invoice Price % Change").Value)
Dim netPricePercentChange = CSng(row.Cells("Net Price % Change").Value)
Dim tradespendPricePercentChange = CSng(row.Cells("Trade Spend % Change").Value)
Dim dnnsiPercentChange = CSng(row.Cells("DNNSI % Change").Value)
Dim cogsPercentChange = CSng(row.Cells("COGS % Change").Value)
Dim grossProfitPercentChange = CSng(row.Cells("Gross Profit % Change").Value)
If invoicePricePercentChange > Single.Epsilon Then
row.Cells("Invoice Price % Change").Style.ForeColor = Color.Green
Else
row.Cells("Invoice Price % Change").Style.ForeColor = Color.Red
End If
If netPricePercentChange > Single.Epsilon Then
row.Cells("Net Price % Change").Style.ForeColor = Color.Green
Else
row.Cells("Net Price % Change").Style.ForeColor = Color.Red
End If
If tradespendPricePercentChange > Single.Epsilon Then
row.Cells("Trade Spend % Change").Style.ForeColor = Color.Green
Else
row.Cells("Trade Spend % Change").Style.ForeColor = Color.Red
End If
If dnnsiPercentChange > Single.Epsilon Then
row.Cells("DNNSI % Change").Style.ForeColor = Color.Green
Else
row.Cells("DNNSI % Change").Style.ForeColor = Color.Red
End If
If cogsPercentChange > Single.Epsilon Then
row.Cells("COGS % Change").Style.ForeColor = Color.Green
Else
row.Cells("COGS % Change").Style.ForeColor = Color.Red
End If
If grossProfitPercentChange > Single.Epsilon Then
row.Cells("Gross Profit % Change").Style.ForeColor = Color.Green
Else
row.Cells("Gross Profit % Change").Style.ForeColor = Color.Red
End If
Next
Catch ex As Exception
Logging.ErrorHandler(ex)
End Try
End Sub
自從我在 SO 上實際發布了一些東西以來已經有一段時間了,但是我們開始了。
使用 _RowsAddedEvent 將自定義樣式應用於您的網格單元格,其他所有內容只會占用太多 CPU。 如果你最近問這個問題,CPU 周期對你很重要。
因此,下面是根據基礎數據綁定項的值繪制單元格的代碼。
private void grid_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
for ( int i = e.RowIndex; i <= e.RowIndex + e.RowCount - 1; i++)
{
var row = grid.Rows[i];
var item = row.DataBoundItem as MovieViewerDataItem;
if (item == null) continue;
var cell = row.Cells["FullPath"];
if ( item.FullPath.StartsWith("u:", StringComparison.InvariantCultureIgnoreCase))
{
cell.Style.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFF2CC");
}
else if( item.FullPath.StartsWith("m:", StringComparison.InvariantCultureIgnoreCase))
{
cell.Style.BackColor = System.Drawing.ColorTranslator.FromHtml("#E2EFDA");
}
}
}
//After Done Binding DataGridView Data
foreach(DataGridViewRow DGVR in DGV_DETAILED_DEF.Rows)
{
if(DGVR.Index != -1)
{
if(DGVR.Cells[0].Value.ToString() == "البدلات")
{
CurrRType = "البدلات";
DataGridViewCellStyle CS = DGVR.DefaultCellStyle;
CS.BackColor = Color.FromArgb(0,175,100);
CS.ForeColor = Color.FromArgb(0,32,15);
CS.Font = new Font("Times New Roman",12,FontStyle.Bold);
CS.SelectionBackColor = Color.FromArgb(0,175,100);
CS.SelectionForeColor = Color.FromArgb(0,32,15);
DataGridViewCellStyle LCS = DGVR.Cells[DGVR.Cells.Count - 1].Style;
LCS.BackColor = Color.FromArgb(50,50,50);
LCS.SelectionBackColor = Color.FromArgb(50,50,50);
}
else if(DGVR.Cells[0].Value.ToString() == "الإستقطاعات")
{
CurrRType = "الإستقطاعات";
DataGridViewCellStyle CS = DGVR.DefaultCellStyle;
CS.BackColor = Color.FromArgb(175,0,50);
CS.ForeColor = Color.FromArgb(32,0,0);
CS.Font = new Font("Times New Roman",12,FontStyle.Bold);
CS.SelectionBackColor = Color.FromArgb(175,0,50);
CS.SelectionForeColor = Color.FromArgb(32,0,0);
DataGridViewCellStyle LCS = DGVR.Cells[DGVR.Cells.Count - 1].Style;
LCS.BackColor = Color.FromArgb(50,50,50);
LCS.SelectionBackColor = Color.FromArgb(50,50,50);
}
}
}
讓它變得簡單
private void dataGridView1_cellformatting(object sender,DataGridViewCellFormattingEventArgs e)
{
var amount = (int)e.Value;
// return if rowCount = 0
if (this.dataGridView1.Rows.Count == 0)
return;
if (amount > 0)
e.CellStyle.BackColor = Color.Green;
else
e.CellStyle.BackColor = Color.Red;
}
看看單元格格式
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.