BUG: Datagrid Is Not Painted Correctly After Adding Split (215490)



The information in this article applies to:

  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual C++, 32-bit Enterprise Edition 6.0
  • Microsoft Visual C++, 32-bit Professional Edition 6.0
  • Microsoft Visual C++, 32-bit Learning Edition 6.0

This article was previously published under Q215490

SYMPTOMS

When you add a split to a Microsoft DataGrid ActiveX control (version 6.0), the scrollbar area of one split in the DataGrid is not painted correctly. The application keeps sending WM_PAINT and WM_ERASEBKGND messages, and the CPU usage can jump as high as 98 percent.

CAUSE

This is caused by a bug in the Microsoft DataGrid ActiveX control.

RESOLUTION

To work around this problem, set the width of the first split explicitly and restrict the user from interactively resizing the width of the split with the following sample code:

Visual C++ Sample Code

void CTestView::OnButton1() 
{
   CSplits splitsCollection = m_DataGrid.GetSplits();

   //Get the column collection.
   CSplit defaultSplit = splitsCollection.GetItem(COleVariant(0L));
   CColumns colSplit0=defaultSplit.GetColumns();

   //Keep the second column, and hide all others.
   for (int i=0; colSplit0.GetCount(); i++)
   {
      if(i != 1)
      {
         colSplit0.GetItem(COleVariant((long)i)).SetVisible(false);
      }
   }

   CSplit newSplit = splitsCollection.Add(1);

   //Set the default split sizemode to fixed, and
   //prevent the user from splitting again.
   defaultSplit.SetSizeMode(1);

   //Set the width of the split to the width of the column.
   float width = colSplit0.GetItem(COleVariant(1L)).GetWidth();
   defaultSplit.SetSize(COleVariant(width));

   //Do not allow the user to resize the column.
   defaultSplit.SetAllowSizing(false);

   //Get the new column collection of the new split.
   CColumns colSplit1 = newSplit.GetColumns();

   //Keep all columns, except the second column.
   for ( i=0; colSplit1.GetCount(); i++)
   {
      if(i!=1)	                                                                                
        coSplit1.GetItem(COleVariant((long)i)).SetVisible(true);
   }

   //Prevent the user from splitting again.
   newSplit.SetSizeMode(1);
}
				

Visual Basic Sample Code

Private Sub Command1_Click()
   With DataGrid1
        For I = 1 To .Splits(0).Columns.Count - 1
           .Splits(0).Columns(I).Visible = False
        Next I
        
        .Splits.Add (1)
        
        .Splits(0).SizeMode = dbgExact
        .Splits(0).Size = .Splits(0).Columns(0).Width
        
        .Splits(0).AllowSizing = False
        
        .Splits(1).Columns(0).Visible = False
        For I = 1 To .Splits(1).Columns.Count - 1
           .Splits(1).Columns(I).Visible = True
        Next I
        
        .Splits(1).SizeMode = dbgExact
   End With
End Sub
				

STATUS

Microsoft has confirmed that this is a bug in the Microsoft DataGrid control included with Visual Studio version 6.0.

MORE INFORMATION

Steps to Reproduce Behavior

To reproduce the problem in Visual C++, do the following:
  1. Create an MFC dialog-based application.
  2. Insert a Microsoft ADO Data control and a Microsoft DataGrid ActiveX control into the dialog box.
  3. Set up the ADO Data Control to point to a data source, and set the DataSource property of the DataGrid control to the ADO Data control.
  4. Use the ClassWizard to generate class wrappers for DataGrid control.
  5. Add a button to the form, and insert the following code for the button click handler:
    class TestView::OnButton1()
    {
       CSplits splitsCollection = m_DataGrid.GetSplits();
    
       //Get the column collection.
       CSplit defaultSplit=splitsCollection.GetItem(COleVariant(0L));
       CColumns colSplit0=defaultSplit.GetColumns();
    	
       //Keep the second column, and hide all the other columns.
       for (int i=0; colSplit0.GetCount(); i++)
       {
         if(i != 1)
           colSplit0.GetItem(COleVariant((long)i)).SetVisible(false);
       }
    
       //Add the new split.
       CSplit newSplit = splitsCollection.Add(1);
    
       //Get the new column collection of the new split.
       CColumns colSplit1 = newSplit.GetColumns();
      
       //Hide the second column, and make all the other columns visible.
       for ( i=0; colSplit1.GetCount(); i++)
       {
          if(i!=1)
            colSplit1.GetItem(COleVariant((long)i)).SetVisible(true);
       }
    }
    						
    The code splits the DataGrid control and hides all of the columns for the first split, except for the second column. The second split hides the second column and displays all the other columns.
  6. Run the application, click the button, and move the splitter bar to the right until it exceeds the size of the first column. Notice that the control is continually repainted and the control (especially the scrollbar area) is not painted properly.
To reproduce the problem in Visual Basic, do the following:
  1. Create a new Visual Basic EXE Project with one form.
  2. Insert a Microsoft ADO Data control and a Microsoft DataGrid ActiveX control into the form.
  3. Set up the ADO Data Control to point to a data source, and set the DataSource property of the DataGrid control to the ADO Data control.
  4. Add a button on the form, and insert the following code for the button click handler:
    Private Sub Command1_Click()
       With DataGrid1
            For I = 1 To .Splits(0).Columns.Count - 1
               .Splits(0).Columns(I).Visible = False
            Next I
           
            .Splits.Add (1)
            
            For I = 1 To .Splits(1).Columns.Count - 1
               .Splits(1).Columns(I).Visible = True
            Next I
       End With
    End Sub
    						

Modification Type:MajorLast Reviewed:12/5/2003
Keywords:kbBug kbCtrl kbMDACNoSweep kbVBX KB215490