วิธีการเปลี่ยนสีแถวใน datagridview?


143

ฉันต้องการเปลี่ยนสีของแถวใดแถวหนึ่งใน DataGridview ของฉัน แถวควรเปลี่ยนเป็นสีแดงเมื่อค่าของ columncell 7 น้อยกว่าค่าใน columncell 10 คำแนะนำใด ๆ เกี่ยวกับวิธีการทำสิ่งนี้ให้สำเร็จ?

คำตอบ:


192

คุณจำเป็นต้องวนซ้ำแถวใน 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; 
     }

1
ขอบคุณสำหรับความช่วยเหลือ Ricardo ฉันลองใช้รหัสที่คุณแนะนำ ฉันยังไม่สามารถใช้งานได้ คุณช่วยลองดูรหัสนี้แล้วบอกฉันทีว่าฉันทำผิดไปได้ไหม? ฉันเป็นนักเรียน C # คนแรก ฉันแน่ใจว่าฉันไม่ได้เขียนรหัสเปรียบเทียบอย่างถูกต้อง foreach (แถว DataGridView ในผู้ขาย DataGridView.Rows) {if (row.Cells [7] .Value คือ <row.Cells [10] .Value) {dataGridViewTextBoxColumn7DefaultCellStyle.BackColor = red; }} ฉันขอขอบคุณสำหรับความช่วยเหลือของคุณ EB
EB

EB ฉันเพิ่มรหัสใหม่ตามรหัสที่คุณให้ไว้ ซินแทกซ์ของคุณปิดไปเล็กน้อยลองใช้โค้ดที่ฉันเพิ่งเพิ่มไปด้านบน
Ricardo Sanchez

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
มันใช้งานได้ดี นอกจากนี้หลังจากเรียงลำดับความสดชื่นในวิธีที่ถูกต้อง
macmuri

24

คุณกำลังมองหาCellFormattingเหตุการณ์
นี่คือตัวอย่าง


2
ความแตกต่างของวิธีการนี้คือเซลล์ทุกเซลล์จะถูกเปรียบเทียบเมื่อเทียบกับเซลล์เดียว อาจเป็นปัญหาด้านประสิทธิภาพหากคุณมีหลายร้อยเซลล์
Ricardo Sanchez

21

ฉันมีปัญหาในการเปลี่ยนสีของตัวอักษรเช่นกัน - ฉันไม่เคยเห็นการเปลี่ยนสีเลย

จนกว่าฉันจะเพิ่มรหัสเพื่อเปลี่ยนสีข้อความเป็นเหตุการณ์DataBindingsCompleteสำหรับDataGridViewสำหรับหลังจากนั้นก็ใช้งานได้

ฉันหวังว่านี่จะช่วยให้ผู้ที่ประสบปัญหาเดียวกัน


text coulour ไม่เปลี่ยนแปลงเมื่ออยู่ในการแทนที่ 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;
}

ขอขอบคุณสำหรับความช่วยเหลือของคุณ. คำแนะนำของคุณใกล้เคียงที่สุดที่ฉันได้รับในการแก้ปัญหา แต่ฉันได้รับข้อผิดพลาดโดยบอกว่า "ค่า" ไม่มีอยู่ในบริบทหรือ "เซลล์" ไม่มีอยู่ในบริบท พยายามคิดออก ...
EB

บรรทัดของรหัสนี้ (dgvr.Cells [7] .Value <dgvr.Cells [10] .Value) ทำให้ฉันมีข้อผิดพลาดนี้ตัวดำเนินการ '<' ไม่สามารถใช้กับตัวถูกดำเนินการประเภท 'วัตถุ' และ 'วัตถุ'
EB

ส่งไปที่ Integer แล้ว :-) สิ่งที่ชอบ: Convert.ToInt32 (dvgr.Cells [7] .Value) <Convert.ToInt32 (dgvr.Cells [10] .Value)
Demi

8

บางคนชอบที่จะใช้Paint, CellPaintingหรือCellFormattingเหตุการณ์ที่เกิดขึ้น แต่ทราบว่าการเปลี่ยนรูปแบบในเหตุการณ์เหล่านี้ทำให้เกิดการโทร recursive หากคุณใช้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 / 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;
            }
        }

0

ฉันมักจะชอบที่จะใช้เหตุการณ์ GridView.RowDataBound สำหรับสิ่งนี้

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

1
เขาถูกถามถึง DatagridView ใน Window Application และคำตอบของคุณเกี่ยวกับ GridView ของเว็บ
ประตูชัย 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;
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.