We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

UserControl in grid results in an hdc error

Hi, I have a problem using a UserControl in a grid. All that I do is to have a UserControl with a panel, 2 labels in it, and assign the control to a cell. When scrolling the grid, I get an hdc error. I made a sample app to reproduce the error. See the attached zip. I am using Syncfusion version 2.1.0.15. I cant upload a file. I attach the source code: Thanks for your help //////////////////////////////////// UserControl /////////////////////////////////// public class UserControl : System.Windows.Forms.UserControl { private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public UserControl() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.panel1 = new System.Windows.Forms.Panel(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.panel1.SuspendLayout(); this.SuspendLayout(); // // panel1 // this.panel1.Controls.Add(this.label1); this.panel1.Controls.Add(this.label2); this.panel1.Controls.Add(this.label3); this.panel1.Location = new System.Drawing.Point(10, 9); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(363, 65); this.panel1.TabIndex = 0; // // label1 // this.label1.Location = new System.Drawing.Point(22, 18); this.label1.Name = "label1"; this.label1.TabIndex = 0; this.label1.Text = "label1"; // // label2 // this.label2.Location = new System.Drawing.Point(130, 20); this.label2.Name = "label2"; this.label2.TabIndex = 0; this.label2.Text = "label1"; // // label3 // this.label3.Location = new System.Drawing.Point(233, 17); this.label3.Name = "label3"; this.label3.TabIndex = 0; this.label3.Text = "label1"; // // UserControl // this.Controls.Add(this.panel1); this.Name = "UserControl"; this.Size = new System.Drawing.Size(379, 88); this.panel1.ResumeLayout(false); this.ResumeLayout(false); } #endregion } //////////////////////////////////////////////// Code in form construtor: gridControl1.CoveredRanges.Add(GridRangeInfo.Cells(20, 1, 20, 2)); gridControl1[20, 1].CellType = "Control"; gridControl1[20, 1].Control = new UserControl();

12 Replies

AD Administrator Syncfusion Team December 22, 2004 09:29 AM UTC

I can see the problem. Thanks for the sample code. I will forward this to development so we can get it fixed. It seems to be the lables on the panel on the usercontrol that is causing the problem. If I change the labels to TextBoxes, the problem goes away for me. As a work around until there is a release with this corrected, here are some workarounds. 1) If you put the labels directly on the UserControl and not on a panel in the UserControl, things draw OK for me. 2) You could also change the labels to textboxes and disable the textboxes some how (might require a derived textbox to make it look nice). 3)If you need the panel, then another work-around that work for me was the hide the labels on the panel, and handle teh panel Draw event and draw the text of the labels in the event handler.
public UserControl()
{
	// This call is required by the Windows.Forms Form Designer.
	InitializeComponent();

	this.label1.Hide();
	this.label2.Hide();
	this.label3.Hide();
	this.panel1.Paint += new PaintEventHandler(panel1_Paint);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
	e.Graphics.DrawString(this.label1.Text, this.label1.Font,  Brushes.Black, this.label1.Location.X, this.label1.Location.Y);
	e.Graphics.DrawString(this.label2.Text, this.label2.Font,  Brushes.Black, this.label2.Location.X, this.label2.Location.Y);
	e.Graphics.DrawString(this.label3.Text, this.label3.Font,  Brushes.Black, this.label3.Location.X, this.label3.Location.Y);
}


AD Administrator Syncfusion Team December 22, 2004 02:24 PM UTC

It seems the Label has double buffering turned on by default when it is on a Panel. In order for our Control celltype to function properly, double buffering must be disabled. Here is some code. //in OnInitialize MakeUnBuffered(this.panel1); //method private void MakeUnBuffered(Control c) { System.Reflection.MethodInfo mInfo = typeof(Control).GetMethod("SetStyle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic); if(mInfo != null) { mInfo.Invoke(c, new object[]{ControlStyles.DoubleBuffer, false}); } if(c.Controls.Count > 0) { foreach (Control c1 in c.Controls) { c1.CausesValidation = false; MakeUnBuffered(c1);//recursive call } } } You can see a sample use of this technique in the grid\samples\databound\repeatercontrol sample.


MM Michael Mann December 23, 2004 11:06 AM UTC

Hi Clay, thanks for your hints and answers. With double buffering disabled the control is working well. I used the panels because of layout problems, when using the control in different sizes. But there''s another problem: not all components within the control are displayed in the grid. Only if the cell containing the control gets the focus, the control is properly displayed. When the cell loses focus the control "hides" some controls again. Any hints or guesses? Thanks in advance - I wish you merry christmas and a happy new year! Michael Mann


AD Administrator Syncfusion Team December 24, 2004 12:10 AM UTC

This may still be the double buffer problem. Are you calling the MakeUnBuffererd method on teh UserControl itself (not just the panels)? When the grid is displaying an inactive cell, it is trying to display a bitmap (not the actual control). To get this bitmap, it draws the control off the screen (say at -1000, -1000, and then snaps a bitmap of it, and then draws the bitmap where the cell is located to display an inactive version fo your control. Somehow, what you are doing is not working with this process. If you can upload a small sample project (to support@syncfusion.com and menthod this tread in teh subject line) showing the problem, we can try to debug it here.


MM Michael Mann January 3, 2005 09:09 AM UTC

Hi Clay, thanks. I sent you an email with a sample project. Michael Mann


AD Administrator Syncfusion Team January 3, 2005 01:05 PM UTC

I got your sample, thank you. One problem I see is that backcolor do not appear in labels unless the control is the currentcell. I will update this thread when I have more information on the problem. Drawing the labels yourself as suggested above does seem to work ok to always display the background.


MM Michael Mann January 17, 2005 05:50 AM UTC

Hi Clay, is there any update on this thread? It''s because we have to kick-off a prototype at the end of january and I wanted to know if there''s a possibility to get it fixed or to offer a workaround. Thanks in advance Michael Mann


AD Administrator Syncfusion Team January 17, 2005 06:19 AM UTC

The System.Windows.Forms.Label class seems to intercept WM_PRINT messages and in such case does not call PaintBackground. There is not much we can do to change this other than to derive the Label class and add code that draws the backcolor, e.g.
private void Form1_Load(object sender, System.EventArgs e)
{
	//UserControl uc = new UserControl();
	//Label l = new Label();
	Panel uc = new Panel();
	Label l = new CustomLabelWithBackColor();                     
	//MakeUnBuffered(l);
	l.Text = "Text";
	l.BackColor = Color.Red;
	l.Bounds = new Rectangle(5, 5, 50, 50);//DockStyle.Fill;
	uc.Controls.Add(l);
	this.gridControl1[2,2].CellType = "Control";
	this.gridControl1[2,2].Control = uc;
	this.gridControl1.RowHeights[2] = 50;
	this.gridControl1.ColWidths[2] = 100;
}

 
public class CustomLabelWithBackColor : Label
{
	protected override void OnPaint(PaintEventArgs e)
	{
		// either do manually call OnPaintBackground
		this.OnPaintBackground(e);

		// or simply draw background here
//                   using (SolidBrush brush = new SolidBrush(BackColor))
//                   {
//                         e.Graphics.FillRectangle(brush, e.ClipRectangle);
//                   }

                     base.OnPaint (e);
	}
}


MM Michael Mann January 18, 2005 05:45 AM UTC

Hi Clay, it''s not just the labels, the main focus in that control lies on a syncfusion gradient label. That means I have to do the same for your gradient labels? Please see the attached sample. Thanks Michael Mann UserControlInGridText_2327.zip


AD Administrator Syncfusion Team January 18, 2005 06:08 AM UTC

Yes. The GradientLabel derives from Label, so it inherits this same behavior oof not drawing the background. Here is you sample back with the gradient labels showing. http://www.syncfusion.com/forums/Uploads/label_problem.zip


MM Michael Mann January 20, 2005 08:41 AM UTC

Hi Clay, thanks for the sample. It works fine unless you''re using controls that are in front or in the back of another control. While the cell hasn''t the focus only controls are painted in the cell, that have the highest z-order. When activating the cell, everything is painted well, and the z-order is displayed correct. What I want to describe with it, is, that it seems that the order is inverted between active and inactive state. When I use the same example - see the attached sample - and swap the order of my first tracking bar from the very background to the very top, the control in the cell is painted correct in inactive state, and wrong in active state. Cheers, Michael label_problem_4270.zip


AD Administrator Syncfusion Team January 20, 2005 02:43 PM UTC

The grid code draws the inactive control using a WM_PRINT message. it looks like the System.Windows.Forms.UserControl class reverses the z-order when a WM_PRINT message is sent to it. A workaround here is to manually reverse the order of controls. You can do this by overriding OnPaint. Here is a sample. http://www.syncfusion.com/forums/Uploads/GridLabelsDrawBackground.zip

Loader.
Live Chat Icon For mobile
Up arrow icon