2013-10-24 24 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... 
    } 
}