Respostas:
Você precisa percorrer as linhas no datagridview e comparar os valores das colunas 7 e 10 em cada linha.
Tente o seguinte:
foreach (DataGridViewRow row in vendorsDataGridView.Rows)
if (Convert.ToInt32(row.Cells[7].Value) < Convert.ToInt32(row.Cells[10].Value))
{
row.DefaultCellStyle.BackColor = Color.Red;
}
Eu estava apenas investigando esse problema (então eu sei que essa pergunta foi publicada há quase 3 anos, mas talvez ajude alguém ...), mas parece que uma opção melhor é colocar o código dentro do RowPrePaint
evento para que você não precisa percorrer todas as linhas, apenas as que são pintadas (para que ele tenha um desempenho muito melhor em grande quantidade de dados:
Anexar ao evento
this.dataGridView1.RowPrePaint
+= new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
this.dataGridView1_RowPrePaint);
O código do evento
private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
if (Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[7].Text) < Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[10].Text))
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
}
Você está procurando o CellFormatting
evento.
Aqui está um exemplo.
Também tive problemas para alterar a cor do texto - nunca vi a cor mudar.
Até eu adicionei o código para alterar a cor do texto para o evento DataBindingsComplete
para DataGridView
. Depois disso, funcionou.
Espero que isso ajude as pessoas que enfrentam o mesmo problema.
Algo como o seguinte ... assumindo que os valores nas células sejam Inteiros.
foreach (DataGridViewRow dgvr in myDGV.Rows)
{
if (dgvr.Cells[7].Value < dgvr.Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
}
não testado, portanto, desculpe-me por qualquer erro.
Se você conhece a linha específica, pode pular a iteração:
if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
Algumas pessoas gostam de usar os eventos Paint
, CellPainting
ou CellFormatting
, mas observe que a alteração de um estilo nesses eventos causa chamadas recursivas. Se você o usar, DataBindingComplete
ele será executado apenas uma vez. O argumento para CellFormatting
é que ele é chamado apenas em células visíveis, para que você não precise formatar células não visíveis, mas as formate várias vezes.
Você pode alterar Backcolor
linha por linha usando seu condition.and esta chamada de função após a aplicação Datasource
de DatagridView
.
Aqui está a função para isso. Simplesmente copie e coloque depoisDatabind
private void ChangeRowColor()
{
for (int i = 0; i < gvItem.Rows.Count; i++)
{
if (BindList[i].MainID == 0 && !BindList[i].SchemeID.HasValue)
gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#C9CADD");
else if (BindList[i].MainID > 0 && !BindList[i].SchemeID.HasValue)
gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#DDC9C9");
else if (BindList[i].MainID > 0)
gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#D5E8D7");
else
gvItem.Rows[i].DefaultCellStyle.BackColor = Color.White;
}
}
private void dtGrdVwRFIDTags_DataSourceChanged(object sender, EventArgs e)
{
dtGrdVwRFIDTags.Refresh();
this.dtGrdVwRFIDTags.Columns[1].Visible = false;
foreach (DataGridViewRow row in this.dtGrdVwRFIDTags.Rows)
{
if (row.Cells["TagStatus"].Value != null
&& row.Cells["TagStatus"].Value.ToString() == "Lost"
|| row.Cells["TagStatus"].Value != null
&& row.Cells["TagStatus"].Value.ToString() == "Damaged"
|| row.Cells["TagStatus"].Value != null
&& row.Cells["TagStatus"].Value.ToString() == "Discarded")
{
row.DefaultCellStyle.BackColor = Color.LightGray;
row.DefaultCellStyle.Font = new Font("Tahoma", 8, FontStyle.Bold);
}
else
{
row.DefaultCellStyle.BackColor = Color.Ivory;
}
}
//for (int i= 0 ; i<dtGrdVwRFIDTags.Rows.Count - 1; i++)
//{
// if (dtGrdVwRFIDTags.Rows[i].Cells[3].Value.ToString() == "Damaged")
// {
// dtGrdVwRFIDTags.Rows[i].Cells["TagStatus"].Style.BackColor = Color.Red;
// }
//}
}
Esta é minha solução para alterar a cor para dataGridView com bindingDataSource:
private void dataGridViewECO_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
if (e.ListChangedType != ListChangedType.ItemDeleted)
{
DataGridViewCellStyle green = this.dataGridViewECO.DefaultCellStyle.Clone();
green.BackColor = Color.Green;
DataGridViewCellStyle gray = this.dataGridViewECO.DefaultCellStyle.Clone();
gray.BackColor = Color.LightGray;
foreach (DataGridViewRow r in this.dataGridViewECO.Rows)
{
if (r.Cells[8].Value != null)
{
String stato = r.Cells[8].Value.ToString();
if (!" Open ".Equals(stato))
{
r.DefaultCellStyle = gray;
}
else
{
r.DefaultCellStyle = green;
}
}
}
}
}
Se você vincular a uma (coleção) de objetos concretos, poderá obtê-lo através da propriedade DataBoundItem da linha. (Para evitar verificar seqüências de caracteres mágicas na célula e usar propriedades "reais" do objeto)
Exemplo de esqueleto abaixo:
DTO / POCO
public class Employee
{
public int EmployeeKey {get;set;}
public string LastName {get;set;}
public string FirstName {get;set;}
public bool IsActive {get;set;}
}
Ligação à DataGridView
private void BindData(ICollection<Employee> emps)
{
System.ComponentModel.BindingList<Employee> bindList = new System.ComponentModel.BindingList<Employee>(emps.OrderBy(emp => emp.LastName).ThenBy(emp => emp.FirstName).ToList());
this.dgvMyDataGridView.DataSource = bindList;
}
o manipulador de eventos e a obtenção do objeto concreto (em vez de um DataGridRow e / ou células)
private void dgvMyDataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
Employee concreteSelectedRowItem = this.dgvMyDataGridView.Rows[e.RowIndex].DataBoundItem as Employee;
if (null != concreteSelectedRowItem && !concreteSelectedRowItem.IsActive)
{
dgvMyDataGridView.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.LightGray;
}
}
Eu normalmente gosto de usar o evento GridView.RowDataBound Event para isso.
protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.ForeColor = System.Drawing.Color.Red;
}
}
Funciona no Visual Studio 2010. (Eu tentei e funciona!) Ele pintará sua linha inteira.
datagridview
.CellClick
evento e coloque a próxima linha de código dentro dele.if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)
{
dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
Você não mencionou como o valor é alterado. Eu usei funcionalidade semelhante quando o usuário está inserindo valor. ou seja, entrando e saindo do modo de edição.
Usando o evento CellEndEdit do datagridview.
private void dgMapTable_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
double newInteger;
if (double.TryParse(dgMapTable[e.ColumnIndex,e.RowIndex].Value.ToString(), out newInteger)
{
if (newInteger < 0 || newInteger > 50)
{
dgMapTable[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Red;
dgMapTable[e.ColumnIndex, e.RowIndex].ErrorText
= "Keep value in Range:" + "0 to " + "50";
}
}
}
Você pode adicionar lógica para limpar a notificação de erro de maneira semelhante.
se no seu caso, se os dados forem carregados programaticamente, o evento CellLeave poderá ser usado com o mesmo código.
Com esse código, você altera apenas a cor de fundo das linhas onde o valor do nome da coluna é nulo, outras linhas ainda são as cores padrão
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["columnname"].Value != null)
{
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
}
}
Apenas uma observação sobre a configuração DefaultCellStyle.BackColor
... você não pode configurá-lo para qualquer valor transparente, exceto Color.Empty
. Esse é o valor padrão. Isso implica falsamente (para mim, pelo menos) que cores transparentes sejam aceitáveis. Eles não são. Cada linha que eu defino como uma cor transparente apenas desenha a cor das linhas selecionadas.
Passei muito tempo batendo minha cabeça contra a parede por causa dessa questão.
Cheguei aqui procurando uma solução para o caso em que não uso a ligação de dados. Nada funcionou para mim, mas eu consegui no final com:
dataGridView.Columns.Clear();
dataGridView.Rows.Clear();
dataGridView.Refresh();
Se você é o segundo desenvolvedor mais burro do planeta (eu sendo o mais burro), todas as soluções acima parecem funcionar: CellFormatting, DataSourceChanged e RowPrePaint. Eu prefiro RowPrePaint.
Lutei com isso (por muito tempo) porque precisava substituir meu SelectionBackColor e SelectionForeColor em vez de BackColor e ForeColor, pois eu estava alterando a linha selecionada.
int counter = gridEstimateSales.Rows.Count;
for (int i = 0; i < counter; i++)
{
if (i == counter-1)
{
//this is where your LAST LINE code goes
//row.DefaultCellStyle.BackColor = Color.Yellow;
gridEstimateSales.Rows[i].DefaultCellStyle.BackColor = Color.Red;
}
else
{
//this is your normal code NOT LAST LINE
//row.DefaultCellStyle.BackColor = Color.Red;
gridEstimateSales.Rows[i].DefaultCellStyle.BackColor = Color.White;
}
}