如何在用户对gridview列进行排序后保持格式?

3
当我从数据库中获取数据时,行是有颜色编码的。但是当用户点击列进行排序时,颜色格式化被丢弃,所有行变为白色。我搜索答案,并发现一些人有相同的问题。他们实现了某种事件处理程序(如DataBindingComplete或CellFormatting),以便在排序后保留或重新实例化格式。然而,我无法让这个工作。有人可以解释为什么吗?或者告诉我另一种方法来解决这个问题?
这是从数据库获取数据并填充网格视图的代码。
public static OdbcConnection DbConnection; // Create an object for the DB connection  
public static MainWindow mw = Form.ActiveForm as MainWindow;

public static void TestSqlToGridView()
{
    // https://learn.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();
}

这是我尝试重新启动格式化的方式。
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();
}

但出现了一个问题,当我按列标题进行排序时,似乎事件从未被调用。我需要将其放在特定位置吗?

谢谢帮助!


我的初步想法是:确保你已经附加到事件处理程序。例如,在表单构造函数或designer.cs文件中应该有一行代码,类似于mw.dataGridView.DataBindingComplete += dataGridView_DataBindingComplete; - OhBeWise
@OhBeWise 感谢您的评论!它在某种程度上帮助了我。请将其添加为答案,以便我可以将其标记为解决方案!如果您能/愿意,还可以解释一下为什么我必须附加到事件处理程序。 - Vinnie Novido
它不起作用是因为顺序的问题:SuspendDrawing - DataSource(带有DataBidingComplete事件)- ResumeDrawing。请参见下面我的答案。我会使用另一种加速DataGridView的方法并摆脱暂停。 - Oak_3260548
在我的测试中,挂起/恢复绘图的顺序没有影响任何事情。 - OhBeWise
2个回答

2
“似乎事件从未被调用。我需要指定一个特定的位置吗?”
“是的,有点像。您已经添加了事件处理程序,但您需要订阅(附加)该事件。这可以通过多种方式完成:”
  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;
    
这将会给您所期望的结果:

Colored rows - Not sorted Colored rows - Sorted


为什么?
通过订阅事件,您将附加处理程序以在基础事件完成后运行。否则,它将永远不会被调用。可以多次订阅多个处理程序。例如,以下内容:
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");
}

每次 dataGridView1.DataBindingComplete 触发时,都会产生以下输出:
/*
First
Second
Third
First
*/

请注意只订阅(+=)一次事件 - 否则可能会产生奇怪的结果、资源泄漏和/或拖慢运行时间(例如,当昂贵/大型处理程序被重复附加时)。这可以通过取消订阅(-=)事件来解决。

0

正如您所建议的:

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

这是我做的一种方法,只要使用DataSource填充DataGridView,它就可以正常工作。

但是再看一遍你的代码后,你使用了SuspendDrawing,然后进行数据绑定,最后又ResumeDrawing!那样会禁用此事件


SuspendDrawing函数似乎不影响事件。我没有改变它们的顺序,它仍然与上述解决方案一起工作。不过还是谢谢你的回答! :) - Vinnie Novido
是的,我认为OhBeWise的解决方案是正确的,而我的上一个建议是错误的。但我很高兴你找到了解决方案。 - Oak_3260548

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接