2017-08-01 192 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

相關問題