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


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

17 115

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 на 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();