2017-04-04 3 views
0

Ich habe eine Konsolenanwendung, die eine Formularanwendung (aus einer anderen Klasse) in einem anderen Thread startet.Zugriff auf "RichTextBox" -Komponente von einem anderen Thread

Aber dann möchte ich auf die richTextBox1 Komponente von meiner Hauptklasse, im Hauptthread zugreifen und das wirft einen Fehler, der sagt, dass ich versuche, auf die Komponente von einem anderen Thread zuzugreifen.

Mein Code: (Form-Anwendung)

public partial class ChatGui : Form 
{ 
    public static RichTextBox textBox; 
    public ChatGui() 
    { 
     InitializeComponent(); 
     richTextBox1.ReadOnly = true; 
     richTextBox1.BackColor = SystemColors.Window; 
    } 

    public void WriteLine(string line) 
    { 
     richTextBox1.Text += line+"\r\n"; 
    } 

    private void textBox1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Enter) 
     { 
      WriteLine("[You]: "+textBox1.Text); 
      NetworkManager.SendPacket("rchat_msg " + textBox1.Text.Replace(" ", "%20")); 
      textBox1.Text = ""; 
      e.Handled = true; 
     } 
    } 

    public void Exit() 
    { 
     Application.Exit(); 
    } 

    private void ChatGui_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     e.Cancel = true; 
    } 

} 

Die Hauptkonsolenanwendung

public static void StartRemoteChat() 
    { 
     RemoteChat = true; 
     Program.ChatGui = new ChatGui(); 
     new Thread(new ThreadStart(() => 
     { 
      Application.Run(Program.ChatGui); 
      while (RemoteChat) 
      { 
       // ... 
      } 
     })).Start(); 
    } 

Also, wie kann ich die richTextBox1 Komponente von meinem Haupt-Thread Zugriff (ich einige Variablen ändern wollen der Komponente) ohne dass dieser Fehler passiert?

+1

Auf einer Seite zur Kenntnis, 'Anwendung. Run() 'ist ein ** blockierender ** Anruf. Deine 'while (RemoteChat)' - Schleife wird ** nicht ** berührt, bis das Chat-Formular geschlossen ist **! –

+0

@Idle_Mind oh, du hast Recht! Vielen Dank ! –

Antwort

3

Das Steuerelement gehört dem Thread, der es erstellt. In deinem Fall besitzt der Thread, den du startest, das Formular, weil es es so malt, dass es dein Formular ui thread wird.

Wenn Sie jedoch versuchen, einen anderen Thread zu verwenden, um Änderungen an dem Steuerelement vorzunehmen, wird eine Ausnahme ausgelöst, genau wie Sie sagten. Die Art und Weise, um dies ist, den Faden berufen, die sie geschaffen kommen und die Änderung vornehmen, die Sie so wollen:

richTextBox1.BeginInvoke(new Action(()=> 
{ 
// make changes to control here. 
})); 
-2

versuchen Einstellung folgende Eigenschaft.

RichTextBox.CheckForIllegalCrossThreadCalls=false; 

dies kann Ihnen helfen.

+2

[Nein!] (Http://stackoverflow.com/a/15516124/107625) –

0

eine, die Ihnen helfen kann, die ist „CheckForIllegalCrossThreadCalls = false;“ aber hier (am Anfang) verwendet:

public Form1() 
    { 
     InitializeComponent(); 
     CheckForIllegalCrossThreadCalls = false;    
    } 

die Beratung ist es, jeden Anruf auf „RichTextBox1“ die Aufrufmethode zu verwenden. Diese Methode ermöglicht die Interaktion mit Elementen, die von anderen Threads erstellt wurden. Beispiel:

richTextBox1.Invoke(new Action(() => richTextBox1.Text = "hello word")); 

„CheckForIllegalCrossThreadCalls = false“ ist eine Lösung, die genug Gefahren hat, wenn es in komplexen Programmen verwendet wird. Ich hoffe, ich war hilfreich.

Verwandte Themen