2013-10-24 56 views
3

我寫了一個程序來設計一個Web瀏覽器。我將我的代碼組織到類中。其實我有幾個問題...線程與形式和類

第一個問題:

要訪問的表單元素我在課堂上使用這樣的說法:

Form1 fc = (Form1)Application.OpenForms["form1"]; 

當我打電話元素使用:

fc.listboxObject.SelectedItem; 

我不知道這是否正確,因爲當我使用

`Form1 f=new Form1();` 

它會創建一個新窗體,它不會更新原來的窗體。我將表單中的所有元素設置爲公開。

第二個問題 在我要創建使用線程,因此用戶可以要求在不同的窗口不止一個網頁新網頁窗口的形式。

public void start_new_page() 
    { 
     Form1 f = new Form1(); 
     Application.Run(f); 

    } 

    private void new_page_Click(object sender, EventArgs e) 
    { 
     Thread t = new Thread(new ThreadStart(start_new_page)); 
     t.Start(); 

    } 

當按鈕被點擊我得到以下錯誤: 跨線程操作無效:控制「listboxObject」從比它創建的線程以外的線程訪問。

我搜索了很多我找到的使用invoke的解決方案,我不想使用它,因爲它只會更新原始表單。我想讓每個表單彼此分開,但共享相同的歷史列表和最愛列表。另外,我不能使用Backgroundworker。下面的代碼是其中一個類的方法之一,我在這裏得到錯誤。實際上,在課堂中的所有方法中,我都面臨着這個錯誤。

public void printlistbox(string textname) 
    { 
     Form1 fc = (Form1)Application.OpenForms["form1"]; 
     int count = 0; 
     string line1; 
     System.IO.StreamReader file1 = new System.IO.StreamReader(textname); 
     fc.listboxObject.Items.Clear(); 
     while ((line1 = file1.ReadLine()) != null) 
     { 
      string[] split = line1.Split(new Char[] { '\t' }); 
      count = 0; 
      foreach (string s in split) 
      { 

       if (count == 1) 
        fc.listboxObject.Items.Add(s); 
       count += 1; 
      } 
     } 
     file1.Close(); 

當點擊按鈕打印時,printlistbox函數將被調用。

+6

有一對夫婦的事情,當你剛開始學習語言和麪向對象編程,你應該永遠不會做。使用線程位於該列表的頂部。瀏覽器風格的程序從不需要它。 –

回答

0

當調用「新表格()」你的applcation創建主線程上的某些內容,稱這是在單獨的線程時,你可以創建一個跨操作嘗試這樣做

public void start_new_page() 
    { 
     Dispatcher.Invoke(
       (Action)delegate() 
     { 
      Form1 f = new Form1(); 
      Application.Run(f); 
     }, System.Windows.Threading.DispatcherPriority.Normal); 
    } 
0

你的第二個問題是最簡單的...你不需要在這裏手動創建新線程。這將顯示一個將自動擁有自己的線程的新表單。

private void new_page_Click(object sender, EventArgs e) 
{ 
    Form1 f = new Form1(); 
    f.Show(); 
} 
+0

我以前使用過,但它也給我同樣的錯誤:跨線程操作無效:控制'listboxObject'從一個線程訪問,而不是它創建的線程。 –

+0

這是正確的。您只能從其擁有的線程更改控件。這就是表單對象的'Invoke'方法的用途。 – David

0

如果您從另一個線程讀取/寫入表單上的對象,則必須調用它。

調用示例:

private void Method1(int i) 
{ 
    if (this.InvokeRequired) 
    { 
    Invoke(new MethodInvoker(delegate() { Method1(i); })); 
    } 
    else 
    { 
    // Put your code here... 
    } 
}