Как изменить цвет строки в datagridview?

Я хотел бы изменить цвет определенной строки в моем datagridview. Строка должна быть изменена на красный, если значение columncell 7 меньше значения в columncell 10. Есть предложения, как это сделать?

17 ответов


нужно перебрать строки в datagridview, а затем сравнить значения столбцов 7 и 10 в каждой строке.

попробуйте это:

foreach (DataGridViewRow row in vendorsDataGridView.Rows) 
     if (Convert.ToInt32(row.Cells[7].Value) < Convert.ToInt32(row.Cells[10].Value)) 
     {
         row.DefaultCellStyle.BackColor = Color.Red; 
     }

Я просто изучал этот вопрос (поэтому я знаю, что этот вопрос был опубликован почти 3 года назад, но, возможно, это поможет кому-то... ) но кажется, что лучшим вариантом является размещение кода внутри RowPrePaint событие, так что вам не нужно пересекать каждую строку, только те, которые окрашены (поэтому он будет работать намного лучше на большом количестве данных:

прикрепить к событию

this.dataGridView1.RowPrePaint 
    += new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
        this.dataGridView1_RowPrePaint);

код

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;
    }
}

Вы ищите CellFormatting событие.
здесь - Это пример.


у меня также были проблемы с изменением цвета текста - я никогда не видел изменения цвета.

пока я добавил код, чтобы изменить цвет текста на событие DataBindingsComplete на DataGridView. После этого все сработало.

Я надеюсь, что это поможет людям, которые сталкиваются с той же проблемой.


что-то вроде следующего... предполагая, что значения в ячейках являются целыми числами.

foreach (DataGridViewRow dgvr in myDGV.Rows)
{
  if (dgvr.Cells[7].Value < dgvr.Cells[10].Value)
  {
    dgvr.DefaultCellStyle.ForeColor = Color.Red;
  }
}

непроверенный, поэтому извиняюсь за любую ошибку.

Если вы знаете конкретную строку, вы можете пропустить итерацию:

if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
  dgvr.DefaultCellStyle.ForeColor = Color.Red;
}

некоторые люди любят использовать Paint, CellPainting или CellFormatting события, но обратите внимание, что изменение стиля в этих событиях вызывает рекурсивные вызовы. Если вы используете DataBindingComplete он будет выполняться только один раз. Аргумент CellFormatting это то, что он вызывается только на видимых ячейках, поэтому вам не нужно форматировать невидимые ячейки, но вы форматируете их несколько раз.


вы можете изменить Backcolor строка за строкой, используя ваше условие.и эта функция вызывается после применения Datasource of DatagridView.

вот функция для этого. Просто скопируйте это и поместите его после Databind

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;                   
    //    }
    //}
}

Это мое решение для изменения цвета на dataGridView с помощью 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;
                }
            }

        }

    }
}

Если вы привязываетесь к (коллекции) конкретных объектов, вы можете получить этот конкретный объект через свойство DataBoundItem строки. (Чтобы избежать проверки магических строк в ячейке и использования "реальных" свойств объекта)

пример скелета ниже:

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;}
}       

привязка к 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;
    }       

затем обработчик событий и получение конкретного объекта (вместо DataGridRow и/или ячеек)

        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;
            }
        }

Мне обычно нравится использовать GridView.Событие RowDataBound событие для этого.

protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.ForeColor = System.Drawing.Color.Red;
    }
}

работает в Visual Studio 2010. (Я пробовал, и это работает!) Он будет рисовать все подряд.

  1. создать кнопку для datagridview.
  2. создать CellClick событие и поместите следующую строку кода внутри него.

if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)    
{
    dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}

вы не упомянули, как значение изменяется. Я использовал аналогичную функциональность, когда пользователь вводит значение. т. е. вход и выход из режима редактирования.

С помощью CellEndEdit событие 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";
        }
    }                               
}

вы можете добавить логику для очистки уведомления об ошибках аналогичным образом.

если в вашем случае, если данные загружаются программно, то CellLeave событие можно использовать с тем же кодом.


С помощью этого кода Вы изменяете только backcolor строк, где значение columname равно null другой цвет строк по умолчанию.

       foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells["columnname"].Value != null)
                    {
                        dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
                    }
                 }

просто примечание о настройке DefaultCellStyle.BackColor...вы не можете установить его в любое прозрачное значение, кроме Color.Empty. Это значение по умолчанию. Это ложно подразумевает (для меня, во всяком случае), что прозрачные цвета в порядке. Это не так. Каждая строка, которую я устанавливаю на прозрачный цвет, просто рисует цвет выбранных строк.

Я потратил слишком много времени, бьясь головой о стену над этим вопросом.


int counter = gridEstimateSales.Строки.Граф;

        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;
            }
        }

Я приземлился здесь, ища решение для случая, когда я не использую привязку данных. Ничего не работало для меня, но я получил его в конце с:

dataGridView.Columns.Clear(); 
dataGridView.Rows.Clear();
dataGridView.Refresh();