2

When I fetch data from the database the rows are colorcoded. However when the user clicks on the columns to sort the color formatting is discarded and all the rows become white. I've searched for answers and found some people with the same issue as I. They have implemented some kind of eventhandler (such as DataBindingComplete or CellFormatting) in order to keep or re-instantiate the formatting after the sort. However I don't get this to work. Can someone explain why, or tell me another way I can solve this problem?

This is the code that fetch data from the database and fills the gridview

public static OdbcConnection DbConnection; // Create an object for the DB connection  
public static MainWindow mw = Form.ActiveForm as MainWindow;

public static void TestSqlToGridView()
{
    // https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridview.datasource?view=netframework-4.7.1

    //var mw = Form.ActiveForm as MainWindow;
    ConnectToDB();

    DbConnection.Open();

    BindingSource bindingSource = new BindingSource();

    // Automatically generate the DataGridView columns.
    SuspendDrawing(mw.dataGridView); // wait with drawing until all data is read
    bindingSource.DataSource = GetData( Laddstatus() );
    mw.dataGridView.DataSource = bindingSource;

    SetRowColor(); // Change the rows color           

    mw.dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.ColumnHeader; // Adjusting the size of header cells !!! AllCells = SLOW !!!
    ResumeDrawing(mw.dataGridView); // draw all cells

    // Set the DataGridView control's border.
    mw.dataGridView.BorderStyle = BorderStyle.Fixed3D;

    DbConnection.Close();
}

This is the way I tried to reinitiate the formatting

void dataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    // This event is raised when the contents of the data source 
    // change or when the value of the DataSource, DataMember, or BindingContext 
    // property changes.

    Print("DatabindingComplete!"); //DEBUG
    SetRowColor();
}

But for some reason when I press the column headers to sort it seem like the event is never called. Do I have to put in a specific location?

Thanks for the help!

Vinnie Novido
  • 82
  • 1
  • 11
  • My initial thought: ensure you've attached to the event handler. I.E. You should have a line of code like `mw.dataGridView.DataBindingComplete += dataGridView_DataBindingComplete;` either in the form constructor or in the designer.cs file. – OhBeWise Nov 07 '17 at 16:59
  • @OhBeWise Thanks for your comment! It helped me somehow. Please add it as an answer so I can mark it as a solution! And if you can/want add an explanation to why I have to attach to the event handler. – Vinnie Novido Nov 08 '17 at 09:11
  • It doesn't work because of the sequence: SuspendDrwaing - DataSource (with DataBidingComplete event) - ResumeDrawing. See my answer bellow. I would use another method of speeding DataGridView and get rid of the suspend. – Oak_3260548 Nov 08 '17 at 12:42
  • In my tests, the sequence of suspending/resuming drawing *did not* affect anything. – OhBeWise Nov 08 '17 at 16:11

2 Answers2

1

[I]t seem[s] like the event is never called. Do I have to put in a specific location?

Yes-ish. You've added the event handler, but you need to subscribe (attach) to the event. This can be done multiple ways:

  1. In Design mode by Double-clicking the DataBindingComplete event under Properties -> Events:

    Properties -> Events -> DataBingingComplete (highlighted)

    This stubs an empty handler to your Form.cs file, and attaches to the event in the Form.designer.cs file:

    this.dataGridView1.DataBindingComplete += new System.Windows.Forms.DataGridViewBindingCompleteEventHandler(this.dataGridView1_DataBindingComplete);
    
  2. Programmatically in the form constructor or Load event:

    this.dataGridView1.DataBindingComplete += this.dataGridView1_DataBindingComplete;
    

This should give you the desired results:

Colored rows - Not sorted Colored rows - Sorted


WHY?

By subscribing to an event, you are attaching your handler to be run after the base event has finished. Otherwise, it will never be invoked. It is possible to subscribe multiple handlers multiple times. For example, the following:

this.dataGridView1.DataBindingComplete += DataGridView1_DataBindingComplete1;
this.dataGridView1.DataBindingComplete += DataGridView1_DataBindingComplete2;
this.dataGridView1.DataBindingComplete += DataGridView1_DataBindingComplete3;
this.dataGridView1.DataBindingComplete += DataGridView1_DataBindingComplete1;

private void DataGridView1_DataBindingComplete1(object sender, DataGridViewBindingCompleteEventArgs e)
{
    Console.WriteLine("First");
}

private void DataGridView1_DataBindingComplete2(object sender, DataGridViewBindingCompleteEventArgs e)
{
    Console.WriteLine("Second");
}

private void DataGridView1_DataBindingComplete3(object sender, DataGridViewBindingCompleteEventArgs e)
{
    Console.WriteLine("Third");
}

Would produce the following output every time dataGridView1.DataBindingComplete triggers:

/*
First
Second
Third
First
*/

Take care to only subscribe (+=) to an event once - otherwise it may produce odd results, resource leaks, and/or bog down your run time (ex. When an expensive/large handler is attached repeatedly). This can be countered by unsubscribing (-=) from the event.

OhBeWise
  • 4,985
  • 3
  • 30
  • 53
0

As you suggested yourself:

Private Sub dgwList_DataBindingComplete(sender As Object, e As DataGridViewBindingCompleteEventArgs) Handles dgwList.DataBindingComplete
    Call ColorMyRows()
End Sub

C#:

Private void dgwList_DataBindingComplete(Object sender, DataGridViewBindingCompleteEventArgs e)
{
    ColorMyRows();
}

This is a way I do it and it works as long as you fill the DataGridView using DataSource.

But looking at your code 2nd time, you have SuspendDrawing, then you do the data binding and then you ResumeDrawing again! That will disable this event.

Oak_3260548
  • 1,453
  • 2
  • 14
  • 32
  • The SuspendDrawing function does not appear to affect the event. I haven't change the order of those and it still works with the above mentioned solution. Thanks for your answer though! :) – Vinnie Novido Nov 15 '17 at 12:57
  • Yes, I think that OhBeWise is right with his solution and I was wrong with the my last suggestion. But I'm glad you found a solution. – Oak_3260548 Nov 15 '17 at 16:17