【问题标题】:C# Double Buffering of a panel面板的 C# 双缓冲
【发布时间】:2013-10-20 20:14:51
【问题描述】:

我到处寻找面板的双缓冲,但它们都使用了我太容易混淆的术语。我正在绘制生物节律,并希望有一个移动功能来缓慢地向前移动生物节律。但是,它闪烁很多,所以我需要弄清楚如何阻止它。我尝试穿线,但无济于事,因为穿线仍然会导致闪烁。

以下内容进入计时器: 您可以跳到底部查看它在哪里绘制图形。 基本上,它会刷新、计算和绘制点。

  Panel p = panel1;
        p.Refresh();
        double physical = Math.Sin(2 * Math.PI * t / 23) * 100;
        double emotional = Math.Sin(2 * Math.PI * t / 28) * 100;
        double intellectual = Math.Sin(2 * Math.PI * t / 33) * 100;
        double physicalint = int.Parse(Math.Round(physical).ToString());
        double emotionalint = int.Parse(Math.Round(emotional).ToString());
        double intellectualint = int.Parse(Math.Round(intellectual).ToString());

        Console.WriteLine(physical + " Physical, " + emotional + " Emotional, " + intellectual + " Intellectual.");
        Console.WriteLine(physicalint + " Physical, " + emotionalint + " Emotional, " + intellectualint + " Intellectual.");

        int midpt = p.Width / 2;
        double Mastery = (physicalint + intellectualint) / 2;
        double Passion = (physicalint + emotionalint) / 2;
        double Wisdom = (emotionalint + intellectualint) / 2;
        int mastery = int.Parse(Math.Round(Mastery).ToString());
         int passion = int.Parse(Math.Round(Passion).ToString());
         int wisdom = int.Parse(Math.Round(Wisdom).ToString());
        Results.Text = "Primary Biorhythms\nPhysical: " + physicalint.ToString() + "\nEmotional: " + emotionalint.ToString() + "\nIntellectual: " + intellectualint.ToString();
        Results.Text += "\nSecondary Biorhythms\nWisdom: " + wisdom.ToString() + "\nPassion: " + passion.ToString() + "\nMastery: " + mastery.ToString();


        int eanum = int.Parse(Spread.Text);

        if (mode == 0)
        {


            for (int i = -eanum; i <= eanum; i++)
            {
                double actualheightphy = p.Height / 2;
                double physical2 = Math.Sin(2 * Math.PI * (t + i) / 23) * 100;
                double emotional2 = Math.Sin(2 * Math.PI * (t + i) / 28) * 100;
                double intellectual2 = Math.Sin(2 * Math.PI * (t + i) / 33) * 100;
                if (physical2 < 0) { physical2 = physical2 * 1.45; }
                if (physical2 > 0) { physical2 = physical2 * 1.5; }
                if (emotional2 < 0) { emotional2 = emotional2 * 1.45; }
                if (emotional2 > 0) { emotional2 = emotional2 * 1.5; }
                if (intellectual2 < 0) { intellectual2 = intellectual2 * 1.45; }
                if (intellectual2 > 0) { intellectual2 = intellectual2 * 1.5; }
                actualheightphy -= physical2;
                double actualheightemo = p.Height / 2;
                double actualheightint = p.Height / 2;
                actualheightemo -= emotional2;
                actualheightint -= intellectual2;
                int distancebetween = p.Width / eanum;

                p.CreateGraphics().FillEllipse(Brushes.Red, i * distancebetween + midpt - 5, int.Parse(Math.Round(actualheightphy).ToString()) - 5, 10, 10);
                p.CreateGraphics().FillEllipse(Brushes.Blue, i * distancebetween + midpt - 5, int.Parse(Math.Round(actualheightemo).ToString()) - 5, 10, 10);
                p.CreateGraphics().FillEllipse(Brushes.Green, i * distancebetween + midpt - 5, int.Parse(Math.Round(actualheightint).ToString()) - 5, 10, 10);
                if (i % 7 == 0)
                {
                    p.CreateGraphics().DrawString(i.ToString(), new Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular), Brushes.White, new RectangleF(i * distancebetween + midpt - 5, p.Height - 12, 30, 30));
                }
                if (eanum == 7)
                {
                    p.CreateGraphics().DrawString(i.ToString(), new Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular), Brushes.White, new RectangleF(i * distancebetween + midpt - 5, p.Height - 12, 30, 30));

                }
            }
            p.CreateGraphics().DrawLine(Pens.White, 0, (p.Height) / 2, p.Width, (p.Height) / 2);
            p.CreateGraphics().DrawLine(Pens.White, p.Width / 2, 0, p.Width / 2, p.Height);

            this.CreateGraphics().DrawString("100", new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular), Brushes.Black, new RectangleF(p.Width / 2 + p.Left - 15, -1, 100, 100));
            this.CreateGraphics().DrawString("-100", new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular), Brushes.Black, new RectangleF(p.Width / 2 + p.Left - 15, p.Height + p.Top + 1, 100, 100));
        }

【问题讨论】:

标签: c# graphics drawing double-buffering


【解决方案1】:

一个可能的原因可能是,就CreateGraphics 方法的性质而言,您每次绘制东西时都会创建一个新的Graphics 对象。哪一个被抽到就靠运气了,所以我想它一定会显着闪烁。

因此,获取 p.CreateGraphics() 的返回值并重用,而不是多次调用它;例如:

p.CreateGraphics().FillEllipse(...);
p.CreateGraphics().FillEllipse(...);
p.CreateGraphics().FillEllipse(...);

应该是:

Graphics graphics=p.CreateGraphics();
...
graphics.FillEllipse(...);
graphics.FillEllipse(...);
graphics.FillEllipse(...);

【讨论】:

  • 这个稍微好点,但还是在闪烁。
  • 你换掉了所有的 CreateGraphics() 调用吗?您拥有的不仅仅是那 3 个 - 这可能就是原因 :)
  • 是的,它们都被换掉了。唯一的其他 createGraphics() 在表单上,​​它们只是正在绘制的数字。换句话说,它们不会产生影响。我还应该刷新面板吗?
  • 您不应该这样做,但根据您程序中发生的所有其他事情,它可能会开始“拖尾”(如果发生这种情况,您会明白我的意思!)在这种情况下,您将需要清除。
  • 它确实需要刷新,因为它确实有拖影!还有其他想法吗?
猜你喜欢
  • 2011-11-26
  • 2011-01-05
  • 2010-10-23
  • 1970-01-01
  • 2011-03-05
  • 2011-10-16
  • 2013-03-05
  • 2012-12-18
  • 1970-01-01
相关资源
最近更新 更多