TabPage 不会重新绘制背景图像
我里面有一个 TabControl 和一个 TabPage 。背景图像由连接点的线组成。所以我有一些多边形。所有这些点都保存在存储器中。每个点都有绘制时的时间属性。所以我想利用点之间的延迟重新绘制图片。我有下一个代码
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();”时,它最终会闪烁
我做错了什么?
I have a TabControl and a TabPage inside it. BackgroundImage consists of lines attaching the points. So I have some polygon. All these points are kept in the storage. each point has the time property when it was drawn. So I want to repaint the picture using the delays between points. i have the next code
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();
}
but the picture even doesn't vanish in the beginning of the repainting. it just flash in the end when i do "currTPage.Invalidate();"
What I do wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的代码与 Windows 中的绘画工作方式根本不兼容。这段代码在主线程上运行,就像它应该的那样,但一个线程一次只能做一件事。它无法在睡眠或执行循环的同时绘制窗口。绘制发生在事件处理程序退出并且执行恢复消息循环(由 Application.Run() 启动的循环)之后。当没有更重要的事情要做时,例如处理用户输入,Windows 会查找窗口的任何部分是否被标记为无效(您的 Invalidate())调用并生成 Paint 事件。
您现在大概可以看到发生了什么,您没有实现 Paint 事件。因此它会执行默认绘制,删除您绘制的所有内容并恢复选项卡页的默认外观。你看到任何东西的唯一原因是因为你使用了 Sleep()。
您需要完全重写它。使用间隔值与 Sleep() 相同的计时器。以及一个跟踪点索引的类字段。在 Tick 事件处理程序中,调用 Invalidate() 并递增索引。并实现Paint事件来进行绘图。
Your code is fundamentally incompatible with the way painting works in Windows. This code runs on the main thread, like it should, but a thread can do only one thing at a time. It cannot paint the window at the same time it is sleeping or executing your loop. Painting happens after your event handler exits and execution resumes the message loop, the one started by Application.Run(). When there's nothing more important to do, like handling user input, Windows looks if any part of the window was marked invalid (your Invalidate()) call and generates the Paint event.
You can now probably see what happens, you didn't implement the Paint event. So it does the default drawing, it erases everything you drew and restores the default appearance of the tab page. The only reason you saw anything at all is because you used Sleep().
You'll need to completely rewrite this. Use a Timer with an Interval value that is the same as the Sleep(). And a class field that keeps track of the dot index. In the Tick event handler, call Invalidate() and increment the index. And implement the Paint event to do the drawing.
构造新图形后,您不会将其设置为 TabPage 的新背景。
After you construct the new Graph you are not setting it to be the new background of the TabPage.