0

I need to show a dialog form (MessageForm) over the main Form (ParentForm). The MessageForm contains a panel (mainPanel) on which I add some controls on runtime (the close button and many Labels and LinkLabels). MessageForm has a specific behavior: it must be translucent and, on show, the ParentForm must be inactive:

public MessageForm(FrmGlobalStatus _parent)
{
    InitializeComponent();
    this.TransparencyKey = this.BackColor;

}

protected override void OnPaintBackground(PaintEventArgs pe)
{
    var hb = new HatchBrush(HatchStyle.Percent50,
            System.Drawing.ColorTranslator.FromHtml(HATCH_BACK_COLOR),
            this.TransparencyKey);
    pe.Graphics.FillRectangle(hb, this.DisplayRectangle);
}

private void mainPanel_Paint(object sender, PaintEventArgs pe)
{
    using (System.Drawing.Pen p = new Pen(new SolidBrush(this.BorderColor)))
    {
        if (borderRadius > 0)
        {
            DrawRoundRect(pe.Graphics, p, 0, 0, mainPanel.Width - 1, mainPanel.Height - 1, borderRadius, this.FillColor);
        }
        else
        {
            pe.Graphics.DrawRectangle(p, 0, 0, mainPanel.Width - 1, mainPanel.Height - 1);
        }
    }
}

The function that shows the MessageForm:

public void Show()
{
    LinkLabel newLinkLabel;
    Label newLabel;
    int lastItemBottom = 0;

    if (Items.Count > 0)
    {
        for (int i = 0; i < Items.Count; i++)
        {
            if (Items[i].LinkAreaLength != 0)
            {
                newLinkLabel = new LinkLabel();
                newLinkLabel.Location = new Point(LINKLABEL_H_MARGIN, LINKLABEL_V_MARGIN + i * LINKLABEL_STEP);
                lastItemBottom = newLinkLabel.Bottom;

                newLinkLabel.BackColor = Color.Transparent;
                newLinkLabel.Text = Items[i].Text;
                newLinkLabel.LinkColor = LinkDefaultColor;
                newLinkLabel.ActiveLinkColor = LinkActiveColor;
                newLinkLabel.AutoSize = true;
                newLinkLabel.Links.Add(Items[i].LinkAreaStart, Items[i].LinkAreaLength, Items[i].URL);
                newLinkLabel.VisitedLinkColor = LinkVisitedColor;
                newLinkLabel.Name = LINK_LABEL_FAMILY + i.ToString();
                newLinkLabel.LinkClicked += new LinkLabelLinkClickedEventHandler(LinkClicked);
                newLinkLabel.MouseHover += new EventHandler(Link_MouseHover);
                newLinkLabel.MouseLeave += new EventHandler(Link_MouseLeave);

                //for max label length calculation
                labelsWidth.Add(Convert.ToInt16((newLinkLabel.CreateGraphics().MeasureString(newLinkLabel.Text, newLinkLabel.Font)).Width));

                this.mainPanel.Controls.Add(newLinkLabel);
                newLinkLabel.BringToFront();
            }
            else
            {
                newLabel = new Label();
                newLabel.Location = new Point(LINKLABEL_H_MARGIN, LINKLABEL_V_MARGIN + i * LINKLABEL_STEP);
                lastItemBottom = newLabel.Bottom;

                newLabel.BackColor = Color.Transparent;
                newLabel.Text = Items[i].Text;

                newLabel.Name = LABEL_FAMILY + i.ToString();
                newLabel.AutoSize = true;

                //for max label length calculation
                labelsWidth.Add(Convert.ToInt16((newLabel.CreateGraphics().MeasureString(newLabel.Text, newLabel.Font)).Width));

                this.mainPanel.Controls.Add(newLabel);
                newLabel.BringToFront();
            }
        }
        //centering the mainPanel on MessageForm
        mainPanel.Width = BOX_WIDTH;
        mainPanel.Height = lastItemBottom + 2;// +LINKLABEL_V_MARGIN;
        mainPanel.Location = new Point((Width - mainPanel.Width) / 2, (Height - mainPanel.Height) / 2);
        ShowDialog(parent);
    }
}

'Items' is alist of specific structures that already contains all the text for Label and LinkLabel controls. Well, now the problem: when I Call the Show function from ParentForm, my MessageForm is flickering, and it is enough visiblie for eyes disturbing. How can I eliminate this flickering?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
kirpi4
  • 143
  • 1
  • 1
  • 11
  • You potentially have a *lot* of controls here. Once Items.Count goes over 50 or so, the amount of time takes for the controls to paint themselves can be perceived as flicker. – Hans Passant Jan 22 '13 at 19:53
  • @Hans, I tested this form with maximum 3 labels on a single panel, plus the button. So, my form contains 5 controls only – kirpi4 Jan 23 '13 at 08:45
  • Finaly, I found the answer here. It's a good one: http://stackoverflow.com/questions/12813752/avoid-flickering-in-windows-forms/12816955#12816955 – kirpi4 Jan 23 '13 at 08:50
  • That's a really bad way of doing it. Do it like this instead: http://stackoverflow.com/questions/3718380/winforms-double-buffering/3718648#3718648 – Hans Passant Jan 23 '13 at 12:45
  • @Hans, I've tried your way. The way found by me works much better and clear - the MessageForm pup up without any noise. Tel me, pls: why I should not use this variant, what is wrong with it? – kirpi4 Jan 24 '13 at 14:33
  • It creates the window and fires the Load event while the constructor is still running, very unhealthy. It has wrong pinvoke declarations, 64-bit code should SetWindowsLongPtr(). And uses pinvoke unnecessarily since CreateParams gets the job done as well. Clearly you are happy with what you have, the comment was meant for other SO users that see the question some day. – Hans Passant Jan 24 '13 at 14:40

0 Answers0