Custom Controls Disappear!?!

  • Thread starter Thread starter Dave
  • Start date Start date
D

Dave

Hi,

I am breaking my head over this. I have a custom control that I am in turn
using in another customer control. The internal control is a drawing area
based on the open net cf signature control - the code is the same with some
enhancements for undo. Everything works great about it except one thing.
Initially when the controls load, visually everything is there, then at the
last second, the border on my custom drawing control disappears. No
functionality is lost, but it is like the border is being replaced or
covered by something. I have tried invalidate and refresh methods at
different times during the load, but nothing seems to help. If after the
controls are loaded I then invalidate on a button click, the border
reappears. Has anyone seen anything like this?

Thanks

Dave
 
What's going on in the OnPaint method? At what point in this method are you
painting the border?
 
What's going on in the OnPaint method? At what point in this method are
you
painting the border?

I've tried moving the paint of border before and after the foreach loop that
draws the signature. It doesn't seem to make a difference.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e){

Point previousPoint, currentPoint;

graphics.Clear(this.BackColor);

this.DrawBorder(e.Graphics);

foreach(ArrayList line in totalLines){

if(line.Count == 0)

continue;

previousPoint = (Point)line[0];

for(int x = 1; x < line.Count; x++){

currentPoint = (Point)line[x];

graphics.DrawLine(linePen, previousPoint.X, previousPoint.Y,
currentPoint.X, currentPoint.Y);

previousPoint = currentPoint;

}

}

}

Here is my drawborder code:

private void DrawBorder(Graphics g){

if(BorderStyle == BorderStyle.None) return;

using(Pen p = new Pen(BorderColor)){

switch(BorderStyle){

case BorderStyle.FixedSingle:

g.DrawRectangle(p, 0, 0, this.Width - 1, this.Height - 1);

break;

case BorderStyle.Fixed3D:

g.DrawRectangle(p, this.ClientRectangle);

break;

}

}

}
 
Does your control inherit directly from Control? If so then you might
consider letting the system do all the work with respect to the border. The
code below might be a bit messy but it should work.

public class MyControl : System.Windows.Forms.Control
{
#region Native ============================
[System.Runtime.InteropServices.DllImport("coredll")]
private static extern IntPtr GetCapture();
[System.Runtime.InteropServices.DllImport("coredll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[System.Runtime.InteropServices.DllImport("coredll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int
dwNewLong);
[System.Runtime.InteropServices.DllImport("coredll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
int X, int Y, int cx, int cy, int uFlags);
private const int GWL_STYLE = -16;
private const int GWL_EXSTYLE = -20;
private const int WS_BORDER = 0x00800000;
private const int WS_EX_CLIENTEDGE = 0x00000200;
private const int SWP_NOSIZE = 0x0001;
private const int SWP_NOMOVE = 0x0002;
private const int SWP_NOZORDER = 0x0004;
private const int SWP_NOACTIVATE = 0x0010;
private const int SWP_FRAMECHANGED = 0x0020;
#endregion ================================
private System.Windows.Forms.BorderStyle borderStyle;
public System.Windows.Forms.BorderStyle BorderStyle
{
get
{
return this.borderStyle;
}
set
{
if (this.borderStyle != value)
{
IntPtr hWnd;
this.borderStyle = value;
this.Capture = true;
hWnd = GetCapture();
this.Capture = false;
switch (this.borderStyle)
{
case BorderStyle.None:
{
int index;
index = GetWindowLong(hWnd, GWL_EXSTYLE);
SetWindowLong(hWnd, GWL_EXSTYLE, index & (~WS_EX_CLIENTEDGE));
index = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, index & (~WS_BORDER));
break;
}
case BorderStyle.FixedSingle:
{
int index;
index = GetWindowLong(hWnd, GWL_EXSTYLE);
SetWindowLong(hWnd, GWL_EXSTYLE, index & (~WS_EX_CLIENTEDGE));
index = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, index | WS_BORDER);
break;
}
case BorderStyle.Fixed3D:
{
int index;
index = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, index & (~WS_BORDER));
index = GetWindowLong(hWnd, GWL_EXSTYLE);
SetWindowLong(hWnd, GWL_EXSTYLE, index | WS_EX_CLIENTEDGE);
break;
}
}
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE |
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}
}
}
public MyControl()
{
this.BorderStyle = System.Windows.Forms.BorderStyle.None;
}
}

--
Tim Wilson
..Net Compact Framework MVP

Dave said:
What's going on in the OnPaint method? At what point in this method are you
painting the border?

I've tried moving the paint of border before and after the foreach loop that
draws the signature. It doesn't seem to make a difference.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e){

Point previousPoint, currentPoint;

graphics.Clear(this.BackColor);

this.DrawBorder(e.Graphics);

foreach(ArrayList line in totalLines){

if(line.Count == 0)

continue;

previousPoint = (Point)line[0];

for(int x = 1; x < line.Count; x++){

currentPoint = (Point)line[x];

graphics.DrawLine(linePen, previousPoint.X, previousPoint.Y,
currentPoint.X, currentPoint.Y);

previousPoint = currentPoint;

}

}

}

Here is my drawborder code:

private void DrawBorder(Graphics g){

if(BorderStyle == BorderStyle.None) return;

using(Pen p = new Pen(BorderColor)){

switch(BorderStyle){

case BorderStyle.FixedSingle:

g.DrawRectangle(p, 0, 0, this.Width - 1, this.Height - 1);

break;

case BorderStyle.Fixed3D:

g.DrawRectangle(p, this.ClientRectangle);

break;

}

}

}
 
Thanks Tim,

I haven't tried what you offered yet, but I just found what is causing the
problem: When the WaitCursor is in front of the control, and then returns to
the default cursor, the border disappears. It seems that something is
missing from the Resize override in my custom control (signature capture
control from the open net cf)? Is there anything you can suggest? I posted
this information to open net cf as well.

Dave
 
Thanks Tim,

I haven't tried what you offered yet, but I just found what is causing the
problem: When the WaitCursor is in front of the control, and then returns to
the default cursor, the border disappears. It seems that something is
missing from the Resize override in my custom control (signature capture
control from the open net cf)? Is there anything you can suggest? I posted
this information to open net cf as well.

Dave
 
Are you calling the base class method in your override?

protected override void OnResize(EventArgs e)
{
base.OnResize(e);
}
 
Thanks Tim,

I haven't tried what you offered yet, but I just found what is causing the
problem: When the WaitCursor is in front of the control, and then returns to
the default cursor, the border disappears. It seems that something is
missing from the Resize override in my custom control (signature capture
control from the open net cf)? Is there anything you can suggest? I posted
this information to open net cf as well.

Dave
 
Thank You Tim.

That works.

Dave

Tim Wilson said:
To get the border to draw you will need to modify the sources OnPaint method
to pass the stored graphics object instead of the one passed via the
PaintEventArgs object.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
...
this.DrawBorder(graphics); // Instead of "this.DrawBorder(e.Graphics);"
}

Instead, look at the attached solution. I've modified the original source
for the Signature control to include the appropriate system border. If you
run into a conflict with Signature being defined twice, because of the
attached Signature source file and the referenced OpenNETCF dll, then just
rename the one in the source file to something like "CustomSignature".
 
Back
Top