dvcolgan
dvcolgan

Reputation: 7728

Datagridview cell turns black when accessing EditedFormattedValue?

I have a winforms application that uses a datagridview. When I access the EditedFormattedValue of a cell while it is in edit mode, sometimes the whole cell turns black. Is this a feature of the datagridview, perhaps some sort of validation feature I need to turn off?

I have found a couple of other mentions of this problem while googling. None of the threads seem to know what the answer is either:

Here not calling Application.DoEvents solved the problem, but I am not calling DoEvents.
http://www.tek-tips.com/viewthread.cfm?qid=1277303&page=1

http://social.msdn.microsoft.com/Forums/en/winformsdatacontrols/thread/d9bf784d-617d-4a35-8125-fe8f67987fa2
Here no one knew why it was happening, but responders suggest setting the background color to white. That seems like a hack, and I'd like to know why this is happening. Also, changing the background color doesn't remove the black background for me.

Added by barlop

enter image description here

Note there is another cause of this, but since the title here is editedformattedvalue, i'll note this example first.

Example involving EditedFormattedValue as cause.

(when you double click the cell, (thus going into edit mode), it goes black)

namespace simpleblackdgv2
{
    public partial class Form1 : Form
    {
        DataGridView dataGridView1 = new DataGridView();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            // BUG IS THAT WHEN YOU DOUBLE CLICK A CELL, IT GOES BLACK


            dataGridView1.Columns.Add("Column1", "Column1");

            dataGridView1.Rows.Add(1);

            dataGridView1.AllowUserToAddRows = false;


            this.Controls.Add(dataGridView1);


            dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;

        }

        private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {

            // doesn't work
             string str = dataGridView1.CurrentCell.EditedFormattedValue.ToString();



        }


        }
    }

On a related note this is another example of it going black, though not from editedformattedvalue (A previous edit to this question has a longer example, this is a simpler one that cuts to it quicker). The bug shows an issue when the general autosize settings are on - set to allcells, and a specific one is set to None, then it can get buggy depending on how you order the statements, which must be a bug. When setting any specific autosize, set the general to off.

Example Black related to resizing

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace blackdgvcellexample {

public partial class Form1 : Form {

    DataGridView dataGridView1;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

        // autosize rows may be meaningless without that.
        //dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;

        dataGridView1 = new DataGridView();
        this.Controls.Add(dataGridView1);

        dataGridView1.Columns.Add("Column1", "Column1");
        dataGridView1.Columns.Add("Column2", "Column2");
        dataGridView1.Columns.Add("Column3", "Column3");

        dataGridView1.AllowUserToAddRows = false;


         dataGridView1.Rows.Add(5);
        //dataGridView1.Rows.Add(1);

        dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;


    }


    private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {



        dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;


        //dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A
        // dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; //B
        // dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; //C

        // B-Cols, C-rows
        // A, ~B, ~C  WORKS
        // A,B, ~C  WORKS
        // A,~B,C  WORKS
        // A,B,C   WORKS
        // SO IT WAS THE ORDER OF THE LINES THAT MAKES A DIFFERENCE!!!!


        // --- trying not turning any off
        //            dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A
        //           dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; //B        
        //            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; //C

        // Cols, Rows, A  BLACK FIRST CELL REST FINE
        // rows, Cols, A   BLACK FIRST CELL REST FINE
        // cols,A,rows   FINE
        // rows,A,cols  BLACK FIRST CELL REST FINE
        // A, rows, cols   BLACK FIRST CELL
        // A, cols, rows  FINE

        // perhaps unnecessary to autoaize rows. 

        dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A

        dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; 
        dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; 


        // this works
        /*

dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; */

        /* 
         * this works
        dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
        dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A            
        */

        /*
          doesn't work
        dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A            
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; 
          */

        // doesn't work
        //   dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
        //   dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A            

        // so don't mix them. ok

        // this doesn't work

        //            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
        //          dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A            


        // these 3 work in any order
        //  dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
        //  dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
        //  dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; //A            

        // don't mix them. 
        // if you are going to mix them, then turn the generals off and do specifics.
        // this won't work
        //  dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
        //  dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
        //  dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; //A            

        // this works, probably any order too.
        /*
        dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
        dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
        dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;           
        dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;           
        dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        */


    }



}


}

related- https://connect.microsoft.com/VisualStudio/feedback/details/2878864/datagridview-cell-goes-black

Upvotes: 3

Views: 3889

Answers (4)

Toolsmythe
Toolsmythe

Reputation: 599

14 Years later and this is STILL an issue. Worse, according to the link I provide below, this is a known bug AND Microsoft's position is that they are not going to fix it.

So it's on us to find a way around it.

Not sure if my variation of this problem has the same cause as those addressed by the above solutions, but it is certainly addressing the same behavior. And none of the above solutions fixed my problem.

I have a DataGridView that has two columns, a ComboBox column and a TextBox column.

The problem was that occasionally when I expanded the ComboBox, all the options except the selected one had a black background. The ComboBox still worked and if I selected a different item in the drop-down I could then read that one, but everything not selected was black.

I've been chasing this problem for a couple of months and my biggest problem was that I couldn't figure out what caused it to manifest, so it usually worked fine until it didn't.

Until today. I finally figured out how to consistently replicate the problem.

If I was editing another row, say one of the TextBox cells, and then clicked directly on a ComboBox ON A DIFFERENT ROW, that caused the issue.

I found this page, which actually did not fix my problem, but it gave me what I needed to fix it: C#: DataGridViewComboBoxColumn Drop Down Menu Appears All Black

In Nick's tip, he fixed his issue by setting the cell background in the EditingControlShowing event handler. Like I said, that didn't fix it for me, but his example also showed how to set an event handler for a control contained within the cell (he was not doing it to address the issue; it was just something he was doing in EditingControlShowing and I got lucky that he left it in for his example), and while the one he set - SelectedIndexChanged - was not the one I needed, if I set the DropDown handler, I could then set the background color for the CONTROL (as opposed to the CELL).

Observe:

    private void dgvScript_EditingControlShowing( object sender, DataGridViewEditingControlShowingEventArgs e )
    {
        ComboBox cmbBx = e.Control as ComboBox;

        if ( cmbBx != null )
        {
            // Fix the black background on the drop down menu
            cmbBx.BackColor = e.CellStyle.BackColor = SystemColors.Window;

            cmbBx.DropDown -= ComboBoxCell_DropDown;
            cmbBx.DropDown += ComboBoxCell_DropDown;
        }
    }

    private void ComboBoxCell_DropDown( object sender, EventArgs e )
    {
        ComboBox cb = ( ComboBox )sender;
        cb.BackColor = SystemColors.Window;
        cb.SelectedIndex = -1;
    }

This completely fixed my problem. My issue was just with a DataGridViewComboBox cell, but I would bet one could tailor this to any of the supported cell types.

Upvotes: 0

SoloWharf
SoloWharf

Reputation: 43

I had a similar issue and could also not figure out why.

I had this code in my EditingControlShowing because for some reason, this cell would always capitalize the contents when editing even with CharacterCasing set to Normal. This was my workaround:

DataGridViewTextBoxEditingControl control1 = (DataGridViewTextBoxEditingControl)e.Control;    
control1.Text = dataGridView1C.CurrentCell.FormattedValue.ToString();

And the solution was to change that last line of code to this:

control1.Text = dataGridView1C.EditingControl.Text;

There aren't many discussons on this issue and I'm suprised it's still around in 2023.

Upvotes: 2

dvcolgan
dvcolgan

Reputation: 7728

Well, though I haven't been able to figure out why this is happening with the str=dataGridView1.CurrentCell.EditedFormattedValue, I found that using the str=dataGridView1.EditingControl.Text value gets the same value and doesn't mess with the cell formatting. So, I guess that solves my problem.

Upvotes: 6

barlop
barlop

Reputation: 13789

The problem is now mentioned here

https://connect.microsoft.com/VisualStudio/feedback/details/2878864/datagridview-cell-goes-black

Besides the workaround mentioned by dvcolgan that works just for the case of editedformattedvalue.

There is a workaround from viorel mentioned at the ms bug link, that i've tested and works, which is to surround the code with

 BeginInvoke( new Action( ( ) =>
     {
        . . .
     } ) );

The above BeginInvoke technique works for both cases.

Upvotes: 1

Related Questions