Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

UserControl performance

Status
Not open for further replies.

nizarhandal

Programmer
Aug 3, 2006
6
PS
I designed the following user control to scroll SMS messages, one instance of it will work fine but when I declared two on the same form it became very very slow. Here is the OnPaint function and another function for processing smileys.

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

if (bGradientEnabled)
{
// Draw the background
LinearGradientBrush bgbrush1 = new LinearGradientBrush(new Rectangle(0, 0, Width / 2, Height), BackColor, Color.White, LinearGradientMode.Horizontal);
LinearGradientBrush bgbrush2 = new LinearGradientBrush(new Rectangle((Width / 2) - 1, 0, Width / 2, Height), Color.White, BackColor, LinearGradientMode.Horizontal);
e.Graphics.FillRectangle(bgbrush1, 0, 0, Width / 2, Height);
e.Graphics.FillRectangle(bgbrush2, Width / 2, 0, Width / 2, Height);
}

if (bBorderLineEnabled)
{
// Draw the upper and the lower lines
Pen pen = new Pen(clrBorderLineColor, nBorderLineHeight);
e.Graphics.DrawLine(pen, 0, 0, Width, 0);
e.Graphics.DrawLine(pen, 0, Height, Width, Height);
}

if (bRTL)
{
//******************************** Draw String ***********************************************
if ((nPosition + flMessageWidth) < 0)
{
nPosition = Width;
}

float flPaintedPortionsWidth = 0;

for (int i = 0; i <= mDisplayingMsgQueue.Count - 1; i++)
{
if (((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionType == MessagePortionType.TextContent)
{
e.Graphics.DrawString(((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsString, Font, new SolidBrush(ForeColor), nPosition + flPaintedPortionsWidth,
(this.Height / 2) - (e.Graphics.MeasureString(((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsString, Font, new PointF(0, 0), StringFormat.GenericTypographic).Height / 2), StringFormat.GenericTypographic);
flPaintedPortionsWidth += ((MessagePortion)(mDisplayingMsgQueue.ToArray())).GetPortionWidth(Font);
}
else
{
e.Graphics.DrawImage(((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsImage, nPosition + flPaintedPortionsWidth,
(this.Height / 2) - (((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsImage.Height / 2));
flPaintedPortionsWidth += ((MessagePortion)(mDisplayingMsgQueue.ToArray())).GetPortionWidth(Font);
}
}
//********************************************************************************************

//******************************** Delete Message ********************************************
if (mDisplayingMsgQueue.Count > 1)
{
if ((flMessageWidth >= Width) && ((nPosition + ((MessagePortion)(mDisplayingMsgQueue.Peek())).GetPortionWidth(Font)) <= 0))
{
MessagePortion msg = (MessagePortion)mDisplayingMsgQueue.Dequeue();
mOldMsgQueue.Enqueue(msg);
flMessageWidth -= ((MessagePortion)(msg)).GetPortionWidth(Font);
nPosition += ((MessagePortion)(msg)).GetPortionWidth(Font);

if (mNewMsgQueue.Count <= 2)
{
EventArgs ea = new EventArgs();
OnMessageQueueEmpty(ea);
}
}
}
//********************************************************************************************

//******************************** Add Message ***********************************************
if (((nPosition + flMessageWidth) <= Width) || mDisplayingMsgQueue.Count == 0)
{
if (mNewMsgQueue.Count == 0)
{
isNewStarted = false;
}

if (mNewMsgQueue.Count > 0 && mDisplayingMsgQueue.Count == 0 && mOldMsgQueue.Count == 0)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
isNewStarted = true;
}
else if (mNewMsgQueue.Count > 0 && mDisplayingMsgQueue.Count > 0 && mOldMsgQueue.Count == 0)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
isNewStarted = true;
}
else if (mNewMsgQueue.Count == 0 && mDisplayingMsgQueue.Count > 0 && mOldMsgQueue.Count > 0)
{
MessagePortion msg = (MessagePortion)mOldMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
}
else if (mNewMsgQueue.Count > 0 && mDisplayingMsgQueue.Count > 0 && mOldMsgQueue.Count > 0)
{
if (((MessagePortion)(mDisplayingMsgQueue.ToArray()[mDisplayingMsgQueue.Count - 1])).PortionType == MessagePortionType.LogoContent)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
isNewStarted = true;
}
else if (isNewStarted)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
}
else
{
MessagePortion msg = (MessagePortion)mOldMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
}
}
}
//********************************************************************************************
}
else
{
//******************************** Draw String ***********************************************
if ((nPosition - flMessageWidth) > Width)
{
nPosition = 0;
}

float flPaintedPortionsWidth = 0;

for (int i = mDisplayingMsgQueue.Count - 1; i >= 0; i--)
{
if (((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionType == MessagePortionType.TextContent)
{
e.Graphics.DrawString(((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsString, Font, new SolidBrush(ForeColor),
nPosition - flMessageWidth + flPaintedPortionsWidth,
(this.Height / 2) - (e.Graphics.MeasureString(((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsString, Font, new PointF(0, 0), StringFormat.GenericTypographic).Height / 2), StringFormat.GenericTypographic);
flPaintedPortionsWidth += ((MessagePortion)(mDisplayingMsgQueue.ToArray())).GetPortionWidth(Font);
}
else
{
PointF ulCorner = new PointF(nPosition - flMessageWidth + flPaintedPortionsWidth, (this.Height / 2) - (((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsImage.Height / 2));
PointF urCorner = new PointF(nPosition - flMessageWidth + flPaintedPortionsWidth + ((MessagePortion)(mDisplayingMsgQueue.ToArray())).GetPortionWidth(Font), (this.Height / 2) - (((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsImage.Height / 2));
PointF llCorner = new PointF(nPosition - flMessageWidth + flPaintedPortionsWidth, (this.Height / 2) - (((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsImage.Height / 2) + ((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsImage.Height);
PointF[] destPara = {ulCorner, urCorner, llCorner};

e.Graphics.DrawImage(((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsImage, destPara);
flPaintedPortionsWidth += ((MessagePortion)(mDisplayingMsgQueue.ToArray())).GetPortionWidth(Font);
}
}
//********************************************************************************************

//******************************** Delete Message ********************************************
if (mDisplayingMsgQueue.Count > 0)
{
if ((flMessageWidth >= Width) && ((nPosition - ((MessagePortion)(mDisplayingMsgQueue.Peek())).GetPortionWidth(Font)) >= Width))
{
//MessageBox.Show("dd");
MessagePortion msg = (MessagePortion)mDisplayingMsgQueue.Dequeue();
mOldMsgQueue.Enqueue(msg);
flMessageWidth -= ((MessagePortion)(msg)).GetPortionWidth(Font);
nPosition -= ((MessagePortion)(msg)).GetPortionWidth(Font);

if (mNewMsgQueue.Count <= 2)
{
EventArgs ea = new EventArgs();
OnMessageQueueEmpty(ea);
}
}
}
//********************************************************************************************

//******************************** Add Message ***********************************************
if (((nPosition - flMessageWidth) >= 0) || (mDisplayingMsgQueue.Count == 0))
{
if (mNewMsgQueue.Count == 0)
{
isNewStarted = false;
}

if (mNewMsgQueue.Count > 0 && mDisplayingMsgQueue.Count == 0 && mOldMsgQueue.Count == 0)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
isNewStarted = true;
}
else if (mNewMsgQueue.Count > 0 && mDisplayingMsgQueue.Count > 0 && mOldMsgQueue.Count == 0)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
isNewStarted = true;
}
else if (mNewMsgQueue.Count == 0 && mDisplayingMsgQueue.Count > 0 && mOldMsgQueue.Count > 0)
{
MessagePortion msg = (MessagePortion)mOldMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
}
else if (mNewMsgQueue.Count > 0 && mDisplayingMsgQueue.Count > 0 && mOldMsgQueue.Count > 0)
{
if (((MessagePortion)(mDisplayingMsgQueue.ToArray()[mDisplayingMsgQueue.Count - 1])).PortionType == MessagePortionType.LogoContent)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
isNewStarted = true;
}
else if(isNewStarted)
{
MessagePortion msg = (MessagePortion)mNewMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
}
else
{
MessagePortion msg = (MessagePortion)mOldMsgQueue.Dequeue();
mDisplayingMsgQueue.Enqueue(msg);
flMessageWidth += ((MessagePortion)(msg)).GetPortionWidth(Font);
}
}
}
//********************************************************************************************
}

e.Graphics.DrawImage(global::SMS2TV.Properties.Resources.box_down, new Rectangle(this.Width - ((int)(this.Height * 1.5)), 0, (int)(this.Height * 1.5), this.Height));
e.Graphics.DrawString(strShortcode, new Font(new FontFamily(this.Font.FontFamily.Name.ToString()), 30, FontStyle.Bold), new SolidBrush(Color.Black), this.Width - ((int)(this.Height * 1.5)) + ((int)(90 / 1.5)), ((int)(90 / 1.5)), StringFormat.GenericTypographic);
}

private System.Collections.ArrayList SplitMessage(System.Collections.ArrayList paramList, string[] CommandList, int Position, DateTime timestamp)
{
System.Collections.ArrayList list = new System.Collections.ArrayList();
Graphics g = this.CreateGraphics();
string strSentence = "";

if (Position == CommandList.Length)
return paramList;

for (int i = 0; i <= paramList.Count - 1; i++)
{
if (((MessagePortion)(paramList.ToArray())).PortionType == MessagePortionType.TextContent)
{
strSentence = ((MessagePortion)(paramList.ToArray())).PortionContentAsString;

while (strSentence.Length != 0)
{
if (!strSentence.Contains(CommandList[Position]))
{
list.Add(new MessagePortion(strSentence, g, MessagePortionType.TextContent, timestamp));
strSentence = "";
}

else if (strSentence.Equals(CommandList[Position]))
{
list.Add(new MessagePortion(mSmiley.GetImageByCommand(CommandList[Position]), g, MessagePortionType.IconContent, timestamp));
strSentence = "";
}

else
{
if (!strSentence.Substring(0, strSentence.IndexOf(CommandList[Position])).Equals(""))
list.Add(new MessagePortion(strSentence.Substring(0, strSentence.IndexOf(CommandList[Position])),
g, MessagePortionType.TextContent, timestamp));

list.Add(new MessagePortion(mSmiley.GetImageByCommand(CommandList[Position]), g, MessagePortionType.IconContent, timestamp));
strSentence = strSentence.Substring(strSentence.IndexOf(CommandList[Position]) + CommandList[Position].Length,
strSentence.Length - strSentence.IndexOf(CommandList[Position]) - CommandList[Position].Length);
}
}
}
else
{
list.Add((((MessagePortion)(paramList.ToArray()))));
}
}

return SplitMessage(list, CommandList, Position + 1, timestamp);
}

Is this a threading model issue? Any help?
 
your onpaint method is waaaaay too long. Take all that logic out and make it happen before the paint. Then only paint what you need to see.

2 Other things that are slowing you down:

1. You declare brushes and pens on every draw. This is really slow. As an added note, the graphics objects suck at disposing themselves so make sure when you're done with them you .Dispose them. Ifyou declare your brushes and pens as private variables then you won't have to dispose of them until the usercontrol disposes. This will save you on performance on every paint.

2. You are doing faaaaar too much casting. Take this stuff out of the paint event and do it between paints. Casting is a huge performance hit. The line that struck me was

((MessagePortion)(mDisplayingMsgQueue.ToArray())).PortionContentAsString


What you really want to do is

1. Prepare the info to be displayed
2. Display that info with the onpaint event
3. Move to the next piece of info while the previous is being displayed.

And run through a loop that way. hope that helps.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top