1

我里面有一个 TabControl 和一个 TabPage。BackgroundImage 由连接点的线组成。所以我有一些多边形。所有这些点都保存在存储中。每个点在绘制时都有时间属性。所以我想使用点之间的延迟重新绘制图片。我有下一个代码

        Page pg;
        if (storage.book.TryGetValue(currTPage.Name, out pg))
        {
            currTPage.BackgroundImage = new Bitmap(currTPage.Width, currTPage.Height);
            Graphics grap = Graphics.FromImage(currTPage.BackgroundImage);
            grap.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            foreach (Sequence seq in pg.pageSeq)
            {
                Dot startDot = null;
                Pen pen = new Pen(Color.FromArgb(seq.r, seq.g, seq.b), 1);
                foreach (Dot dot in seq.seq)
                {
                    int sX;
                    int sY;
                    if (filter.getPageParameters(currentPattern).orientation == Orientation.Landscape)
                    {
                        if (this.currTPage.Width / (double)this.currTPage.Height >= 1.4)
                        {
                            sX = (int)(dot.x * this.currTPage.Height / pageHeight) + (currTPage.Width - Convert.ToInt32(this.currTPage.Height * Math.Sqrt(2))) / 2;
                            sY = (int)(dot.y * this.currTPage.Height / pageHeight);
                        }
                        else
                        {
                            sX = (int)(dot.x * this.currTPage.Width / pageWidth);
                            sY = (int)(dot.y * this.currTPage.Width / pageWidth) + (currTPage.Height - Convert.ToInt32(this.currTPage.Width / Math.Sqrt(2))) / 2;
                        }
                    }
                    else
                    {
                        if (this.currTPage.Width / (double)this.currTPage.Height <= 1 / 1.4)
                        {
                            sX = (int)(dot.x * this.currTPage.Width / pageWidth);
                            sY = (int)(dot.y * this.currTPage.Width / pageWidth) + (currTPage.Height - Convert.ToInt32(this.currTPage.Width * Math.Sqrt(2))) / 2;
                        }
                        else
                        {
                            sX = (int)(dot.x * this.currTPage.Height / pageWidth) + (currTPage.Width - Convert.ToInt32(this.currTPage.Height / Math.Sqrt(2))) / 2;
                            sY = (int)(dot.y * this.currTPage.Height / pageWidth);
                        }
                    }

                    if (startDot == null)
                    {
                        startDot = new Dot(sX, sY, dot.time, dot.force);
                        continue;
                    }
                    Dot newDot = new Dot(sX, sY, dot.time, dot.force);
                    grap.DrawLine(pen, startDot.x, startDot.y, newDot.x, newDot.y);
                    Thread.Sleep((int)(newDot.time - startDot.time));
                    currTPage.Invalidate(new Rectangle(Math.Min(startDot.x, newDot.x) - 1, Math.Min(startDot.y, newDot.y) - 1, Math.Abs(startDot.x - newDot.x) + 1, Math.Abs(startDot.y - newDot.y) + 1));
                    startDot = newDot;
                }
            }
            currTPage.Invalidate();
        }

但在重绘开始时,画面甚至没有消失。当我执行“currTPage.Invalidate();”时,它最终会闪烁

我做错了什么?

4

2 回答 2

3
     Thread.Sleep((int)(newDot.time - startDot.time));
     currTPage.Invalidate(new Rectangle(...));

您的代码与 Windows 中的绘画工作方式根本不兼容。这段代码在主线程上运行,就像它应该的那样,但是一个线程一次只能做一件事。它不能在睡眠或执行循环的同时绘制窗口。绘制发生您的事件处理程序退出并且执行恢复消息循环之后,该循环由 Application.Run() 启动。当没有更重要的事情要做时,例如处理用户输入,Windows 会查看窗口的任何部分是否被标记为无效(您的 Invalidate())调用并生成 Paint 事件。

您现在可能会看到发生了什么,您没有实现 Paint 事件。因此它会执行默认绘图,它会擦除​​您绘制的所有内容并恢复选项卡页的默认外观。你看到任何东西的唯一原因是你使用了 Sleep()。

你需要完全重写它。使用具有与 Sleep() 相同的 Interval 值的 Timer。还有一个跟踪点索引的类字段。在 Tick 事件处理程序中,调用 Invalidate() 并增加索引。并实现 Paint 事件来进行绘图。

于 2011-09-24T13:52:11.043 回答
0

构建新 Graph 后,您不会将其设置为 TabPage 的新背景。

于 2011-09-24T13:47:06.787 回答