Làm cách nào để thay đổi màu hàng trong datagridview?


143

Tôi muốn thay đổi màu của một hàng cụ thể trong datagridview của tôi. Hàng nên được đổi thành màu đỏ khi giá trị của cột 7 nhỏ hơn giá trị trong cột 10. Có bất kỳ đề xuất nào về cách thực hiện việc này không?

Câu trả lời:


192

Bạn cần lặp qua các hàng trong datagridview và sau đó so sánh các giá trị của cột 7 và 10 trên mỗi hàng.

Thử cái này:

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ảm ơn bạn đã giúp đỡ Ricardo. Tôi đã thử mã bạn đề nghị. Tôi vẫn không thể làm cho nó hoạt động. Bạn có phiền khi xem mã này và cho tôi biết tôi đã sai ở đâu không? Tôi là một sinh viên C # mới bắt đầu. Tôi chắc chắn rằng tôi đã không viết mã so sánh chính xác. foreach (hàng DataGridView trong nhà cung cấpDataGridView.Rows) {if (row.Cells [7] .Value là <row.Cells [10] .Value) {dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } Tôi đánh giá cao sự giúp đỡ của bạn. EB
EB.

EB Tôi đã thêm mã mới dựa trên mã bạn cung cấp. Sintax của bạn đã tắt một chút, hãy thử mã tôi vừa thêm ở trên.
Ricardo Sanchez

2
Ricardo. Tôi đã thay đổi .text thành .value và thay đổi thành DefaultCellstyle.Backcolor = color.red và mã đã hoạt động !!! Cảm ơn bạn đã dành thời gian! EB
EB.

60

Tôi mới chỉ nghiên cứu vấn đề này (vì vậy tôi biết câu hỏi này đã được xuất bản gần 3 năm trước, nhưng có lẽ nó sẽ giúp được ai đó ...) nhưng có vẻ như một lựa chọn tốt hơn là đặt mã bên trong RowPrePaintsự kiện để bạn không phải đi qua từng hàng, chỉ những hàng được vẽ (vì vậy nó sẽ hoạt động tốt hơn nhiều trên lượng dữ liệu lớn:

Đính kèm sự kiện

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

Mã sự kiện

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
Tôi thực sự thích cách bạn nắm bắt vấn đề tận gốc thay vì chờ đợi cho đến khi mọi thứ đã được vẽ. Đây là một cách tiếp cận rất "bên ngoài hộp". Hầu hết mọi người thà đi vòng qua mỗi hàng một lần nữa ...
bird2920

Bên cạnh việc nhanh hơn nhiều, nó cũng giúp thực hiện nó đúng lúc. Tôi gặp vấn đề với các hàng của tôi không được tô màu, có lẽ vì tôi đặt màu không đúng lúc. Với phương pháp này, nó được đảm bảo xảy ra đúng thời điểm.
sanderd17

1
Điều này hoạt động tốt. Ngoài ra sau khi sắp xếp làm mới của nó theo cách chính xác.
macmuri

24

Bạn đang tìm kiếm CellFormattingsự kiện.
Đây là một ví dụ.


2
Sự khác biệt với phương pháp này là mỗi một ô sẽ được so sánh với chỉ một ô. Nó có thể là một vấn đề hiệu suất nếu bạn có hàng trăm tế bào.
Ricardo Sanchez

21

Tôi cũng gặp khó khăn khi thay đổi màu văn bản - tôi chưa bao giờ thấy màu thay đổi.

Cho đến khi tôi thêm mã để thay đổi màu sắc văn bản để các sự kiện DataBindingsCompletecho DataGridView. Sau đó nó hoạt động.

Tôi hy vọng điều này sẽ giúp những người phải đối mặt với cùng một vấn đề.


văn bản coulour không thay đổi khi ghi đè onLoad (..) hoặc sự kiện. DataBindingsComplete là nơi tốt hơn nhiều để thực hiện cài đặt màu của các hàng.
timothy

13

Một cái gì đó như sau ... giả sử các giá trị trong các ô là Số nguyên.

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

chưa được kiểm tra, vì vậy xin lỗi cho bất kỳ lỗi.

Nếu bạn biết hàng cụ thể, bạn có thể bỏ qua Lặp lại:

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

Cảm ơn sự giúp đỡ của bạn. Đề xuất của bạn là gần nhất tôi đã nhận được để giải quyết vấn đề. Nhưng tôi vẫn nhận được lỗi nói rằng "Giá trị" không tồn tại trong ngữ cảnh hoặc "Các ô" không tồn tại trong ngữ cảnh. Đang cố gắng tìm ra nó ...
EB.

dòng mã này (dgvr.Cells [7] .Value <dgvr.Cells [10] .Value) hiện cung cấp cho tôi lỗi này Toán tử '<' không thể áp dụng cho toán hạng loại 'đối tượng' và 'đối tượng'
EB.

Đúc chúng thành Integer, sau đó. :-) một cái gì đó như: Convert.ToInt32 (dvgr.Cells [7] .Value) <Convert.ToInt32 (dgvr.Cells [10] .Value)
Demi

8

Một số người thích sử dụng Paint, CellPaintinghoặc CellFormattingcác sự kiện, nhưng lưu ý rằng việc thay đổi phong cách trong những sự kiện gây ra các cuộc gọi đệ quy. Nếu bạn sử dụng DataBindingCompletenó sẽ chỉ thực hiện một lần. Đối số CellFormattinglà nó chỉ được gọi trên các ô có thể nhìn thấy, vì vậy bạn không phải định dạng các ô không nhìn thấy được, nhưng bạn định dạng chúng nhiều lần.


5

Bạn có thể thay đổi Backcolortừng hàng sử dụng condition.and bạn gọi chức năng này sau khi áp dụng Datasourcecác DatagridView.

Đây là chức năng cho điều đó. Đơn giản chỉ cần sao chép nó và đặt nó sauDatabind

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

Đây là giải pháp của tôi để thay đổi màu sắc thành dataGridView với bindDataSource:

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

Nếu bạn liên kết với một (bộ sưu tập) các đối tượng cụ thể, bạn có thể lấy đối tượng cụ thể đó thông qua thuộc tính DataBoundItem của hàng. (Để tránh kiểm tra các chuỗi ma thuật trong ô và sử dụng các thuộc tính "thực" của đối tượng)

Ví dụ về bộ xương dưới đây:

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

Liên kết với 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;
    }       

sau đó xử lý sự kiện và lấy đối tượng cụ thể (thay vì DataGridRow và / hoặc các ô)

        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

Tôi thường thích sử dụng sự kiện GridView.RowDataBound cho việc này.

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

1
Anh ta được yêu cầu DatagridView trong Window Application. Và câu trả lời của bạn là về GridView của Web.
Pratik 1020

0

Hoạt động trên Visual Studio 2010. (Tôi đã thử và nó hoạt động!) Nó sẽ vẽ toàn bộ hàng của bạn.

  1. Tạo một nút cho datagridview.
  2. Tạo một CellClicksự kiện và đặt dòng mã tiếp theo bên trong nó.

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

0

Bạn đã không đề cập đến cách thay đổi giá trị. Tôi đã sử dụng chức năng tương tự khi người dùng đang nhập giá trị. tức là vào và rời chế độ chỉnh sửa.

Sử dụng sự kiện CellEndEdit của 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";
        }
    }                               
}

Bạn có thể thêm logic để xóa thông báo lỗi theo cách tương tự.

nếu trong trường hợp của bạn, nếu dữ liệu được tải theo chương trình, thì sự kiện CellLeave có thể được sử dụng với cùng một mã.


0

Với mã này, bạn chỉ thay đổi màu nền của hàng trong đó giá trị cột là null các hàng khác màu vẫn là màu mặc định.

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

0

Chỉ cần một lưu ý về cài đặt DefaultCellStyle.BackColor... bạn không thể đặt nó thành bất kỳ giá trị trong suốt nào ngoại trừ Color.Empty. Đó là giá trị mặc định. Điều đó ngụ ý sai (với tôi, dù sao) rằng màu trong suốt là OK. Họ không phải. Mỗi hàng tôi đặt thành một màu trong suốt chỉ vẽ màu của các hàng đã chọn.

Tôi đã dành quá nhiều thời gian đập đầu vào tường về vấn đề này.


0

Tôi đã đến đây để tìm giải pháp cho trường hợp tôi không sử dụng ràng buộc dữ liệu. Không có gì làm việc cho tôi nhưng cuối cùng tôi đã nhận được:

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

0

Nếu bạn là nhà phát triển ngu ngốc thứ hai trên hành tinh (tôi là người câm nhất), tất cả các giải pháp trên dường như đều hoạt động: CellFormatted, DataSourceChanged và RowPrePaint. Tôi thích RowPrePaint.

Tôi đã vật lộn với điều này (vì cách quá lâu) bởi vì tôi cần ghi đè lên SelectionBackColor và SelectionForeColor thay vì BackColor và ForeColor khi tôi đang thay đổi hàng đã chọn.


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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.