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


143

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

Ответы:


192

Вам нужно перебрать строки в сетке данных, а затем сравнить значения столбцов 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; 
     }

1
Спасибо за помощь, Рикардо. Я попробовал код, который вы предложили. Я до сих пор не могу заставить его работать. Не могли бы вы взглянуть на этот код и сказать, где я ошибся? Я начинающий студент C #. Я уверен, что просто не правильно написал код сравнения. foreach (строка DataGridView в vendorsDataGridView.Rows) {if (row.Cells [7]. Значение равно <row.Cells [10] .Value) {dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } Я ценю вашу помощь. EB
EB.

EB Я добавил новый код на основе кода, который вы предоставили. Ваш синтаксис немного отключился, попробуйте код, который я только что добавил выше.
Рикардо Санчес

2
Рикардо. Я изменил .text на .value и изменил на DefaultCellstyle.Backcolor = color.red, и код работал !!! Спасибо за уделенное время! EB
EB.

60

Я только что исследовал эту проблему (так что я знаю, что этот вопрос был опубликован почти 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;
    }
}

3
Мне очень нравится, как вы улавливаете проблему в корне, вместо того, чтобы ждать, пока все не будет расписано. Это очень нестандартный подход. Большинство людей предпочли бы просто перебирать каждый ряд снова ...
bird2920

Помимо того, что он намного быстрее, он также помогает делать это в нужное время. У меня были проблемы с тем, что мои ряды не окрашивались, возможно потому, что я установил цвет в неправильное время. При таком подходе это гарантированно произойдет в нужное время.
sanderd17

1
Это работает. Кроме того, после сортировки его обновления в правильном порядке.
Макмури

24

Вы ищете CellFormattingсобытие.
Вот пример.


2
Разница с этим подходом заключается в том, что каждая отдельная ячейка будет сравниваться, а не только одна. Это может быть проблема с производительностью, если у вас есть несколько сотен ячеек.
Рикардо Санчес

21

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

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

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


текстовый цвет не изменяется при переопределении onLoad (..) или событии. DataBindingsComplete - гораздо лучшее место для настройки цвета строк.
Тимоти

13

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

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

Спасибо за помощь. Ваше предложение - самое близкое, что я получил к решению проблемы. Но я продолжаю получать сообщение о том, что либо «Значение» не существует в контексте, либо «Ячейки» не существует в контексте. Пытаюсь это выяснить ...
Е.Б.

эта строка кода (dgvr.Cells [7] .Value <dgvr.Cells [10] .Value) теперь дает мне эту ошибку. Оператор «<» нельзя применить к операндам типа «объект» и «объект»
EB.

Затем приведите их к Integer. :-) что-то вроде: Convert.ToInt32 (dvgr.Cells [7] .Value) <Convert.ToInt32 (dgvr.Cells [10] .Value)
Деми

8

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


5

Вы можете изменить Backcolorстроку за строкой , используя ваш condition.and вызов этой функции после применения 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;
    }
}

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

2

Это мое решение изменить цвет на 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;
                }
            }

        }

    }
}

1

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

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

DTO / ПОКО

public class Employee
{
    public int EmployeeKey {get;set;}

    public string LastName {get;set;}

    public string FirstName {get;set;}

    public bool IsActive {get;set;}
}       

Привязка к сетке данных

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

0

Я обычно хотел бы использовать событие GridView.RowDataBound Event для этого.

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

1
Его спрашивают о DatagridView в оконном приложении. И ваш ответ о GridView Web.
Pratik 1020

0

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

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

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

0

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

Использование события 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 можно использовать с тем же кодом.


0

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

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

0

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

Я потратил слишком много времени, стуча головой об стену из-за этой проблемы.


0

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

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

0

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

Я боролся с этим (слишком долго), потому что мне нужно было переопределить мои SelectionBackColor и SelectionForeColor вместо BackColor и ForeColor, когда я менял выбранную строку.


0
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;
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.