2017-08-01 197 views
0

我正在创建一个WinForms应用程序,图片框被禁用,默认情况下不可见。当我在窗体中单击单选按钮,我想要的图片框出现,之后,我想绘制了他们的东西:当PictureBox.Visible设置为True时,C#中究竟发生了什么?

// the radio button CheckedChanged event handler: 
table1PictureBox.Enabled = true; 
table1PictureBox.Visible = true; 
DrawCorrectAnswers(); // draw something over the picture box 

的问题是,由画面之前绘制完成可见,所以绘图最终由图片覆盖。

在解决问题时,我读取here,将Visibility设置为true后,实际图像加载在表单的消息队列中排队。答案甚至表明,一种可能的解决方案是设置一个计时器,然后异步等待其刻度,然后进行绘图,以便图片有时间加载。我不喜欢解决方案设置一个计时器,而是我想等待图片本身加载。

有没有办法做到这一点?在这种情况下,设置如何显示真正的工作?


我也试图拿出看起来像这样的一个替代解决方案:

// the radio button CheckedChanged event handler: 
table1PictureBox.Enabled = true; 
table1PictureBox.Visible = true; 
this.BeginInvoke(new Action(() => { DrawCorrectAnswers(); })); // 'this' is the form 

我的想法是,这将排队的消息加载消息后拉伸,所以即使是操作将按照要求的顺序执行。但是,这也不起作用。

在这种情况下,如果我处于窗体的线程中,可能会出现BeginInvoke的特殊行为吗?我甚至尝试了正常的Invoke,令我惊讶的是,它并没有造成僵局。这是为什么?


[编辑]这里是一个说明该问题的小例子:

public Form1() 
    { 
     InitializeComponent(); 

     pictureBox1.Visible = false; 
     pictureBox1.Enabled = false; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     pictureBox1.Enabled = true; 
     pictureBox1.Visible = true; 

     Graphics graphics = pictureBox1.CreateGraphics(); 
     graphics.DrawLine(Pens.Black, 0, 0, 50, 50); 
    } 
+0

添加DrawCorrectAnswers函数的代码,我认为你的问题不是图像加载,而是图片重绘。 – Gusman

+0

@Gusman我加了一个例子。 – honzukka

+0

我添加了一个答案:D – Gusman

回答

2

这里的问题是,你正在利用PictureBox的,在图像上,只要控制被重绘一切你画上它将被删除,你需要重画它。

更好的解决方案是手动加载图像,在图像上绘制文本,然后将其设置为在PictureBox:

private void button1_Click(object sender, EventArgs e) 
{ 

    Bitmap bmp = Bitmap.FromFile(pathToTheFile); 

    using(var graphics = Graphics.FromImage(bmp)) 
     graphics.DrawLine(Pens.Black, 0, 0, 50, 50); 

    var oldImg = pictureBox1.Image; 
    pictureBox1.Image = bmp; 

    if(oldImg != null) 
     oldImg.Dispose(); 

    pictureBox1.Enabled = true; 
    pictureBox1.Visible = true; 

} 

注意一些事情:处置总是你所创建的任何图形对象,并更好用using块包围它。另外,在不需要时处理任何未使用的图像,这就是为什么我检索旧图像并在存在的情况下处理它。

最后,如果您不想将图像作为物理文件包含进来,则可以将其作为资源嵌入,但有很多关于如何操作的示例。

编辑:

当你设置可见的真引擎盖下会发生什么情况是,在PictureBox区域无效的形式,然后在接下来的抽奖周期的形式将测试其可见的控件相交与矩形(或任何其他无效区域),然后将绘制它们。

另外,关于调用,为什么它应该导致死锁?你没有使用任何锁,当你调用Invoke时它将检查线程,如果线程是UI,那么它将执行该函数,否则它会将调用发布到UI线程,并且调用的线程将被阻塞直到UI已经处理了函数调用。

+0

谢谢,这比我的方法更有意义! – honzukka

+0

@honzukka如果答案是正确的,请接受它。 – Gusman

+0

我仍然希望得到我的其他问题的答案。我知道你的方法按照我需要的方式工作,但我仍然不明白我的尝试究竟出了什么问题。有一些概念对我来说还不清楚。那么我错误地说了这个问题吗? (正如你所看到的,这是我在这里的第一篇文章......:D) – honzukka

相关问题