C# 线程中操作窗体控件

Posted dotNET编程大全

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 线程中操作窗体控件相关的知识,希望对你有一定的参考价值。


1. 在线程中给textBox1

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApp12{ public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) {
// CheckForIllegalCrossThreadCalls = false; // Class1 cs1 = new Class1(); Thread th = new Thread(test1); th.Start(); // cs1.ShowEvent = test;
}
public void test1() {
// ShowlbDevTem("123"); textBox1.Text = "123";
}

private void button1_Click(object sender, EventArgs e) {
// ShowlbDevTem("112");
}
/* public void test(string str) {
ShowlbDevTem(str); } public delegate void SWTDelegate(string AddStr); //public delegate void ComsumerTextDelegate(int Index, string AddStr); public void ShowlbDevTem(string AddStr) { if (textBox1.InvokeRequired) { SWTDelegate pd = new SWTDelegate(ShowlbDevTem); textBox1.Invoke(pd, new object[] { AddStr }); } else { textBox1.Text = AddStr; //richTextBox1.AppendText(AddStr); } }
public void dataShow(int row, int column, string str) { row = row % 30; ShowMessage(dataGridViewX1, str, row, column);
}

delegate void ShowMessageDelegate(DataGridView dg, string message, int row, int column); private void ShowMessage(DataGridView dg, string message, int row, int column) { if (dg.InvokeRequired) { ShowMessageDelegate showMessageDelegate = ShowMessage; dg.Invoke(showMessageDelegate, new object[] { dg, message, row, column }); } else {
dg.Rows[row].Cells[column].Value = message; } } */

}}

运行结果:

线程中是不允许直接操作窗体空间的

怎么解决呢?

方法1: CheckForIllegalCrossThreadCalls = false;

运行ok

方法2:委托实现:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApp12{ public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) {
//CheckForIllegalCrossThreadCalls = false; // Class1 cs1 = new Class1(); Thread th = new Thread(test1); th.Start(); // cs1.ShowEvent = test;
}
public void test1() {
ShowlbDevTem("123"); //textBox1.Text = "123";
}

private void button1_Click(object sender, EventArgs e) {
// ShowlbDevTem("112");
}
/* public void test(string str) {
ShowlbDevTem(str); }*/ public delegate void SWTDelegate(string AddStr); //public delegate void ComsumerTextDelegate(int Index, string AddStr); public void ShowlbDevTem(string AddStr) { if (textBox1.InvokeRequired) { SWTDelegate pd = new SWTDelegate(ShowlbDevTem); textBox1.Invoke(pd, new object[] { AddStr }); } else { textBox1.Text = AddStr; //richTextBox1.AppendText(AddStr); } }
/* public void dataShow(int row, int column, string str) { row = row % 30; ShowMessage(dataGridViewX1, str, row, column);
}

delegate void ShowMessageDelegate(DataGridView dg, string message, int row, int column); private void ShowMessage(DataGridView dg, string message, int row, int column) { if (dg.InvokeRequired) { ShowMessageDelegate showMessageDelegate = ShowMessage; dg.Invoke(showMessageDelegate, new object[] { dg, message, row, column }); } else {
dg.Rows[row].Cells[column].Value = message; } } */

}}

C# 线程中操作窗体控件

然后我想在类中对空间进行操作,这样还可以么?

试试看

主窗体代码:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApp12{ public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) {
//CheckForIllegalCrossThreadCalls = false; Class1 cs1 = new Class1(); Thread th = new Thread(cs1.test); th.Start(); // cs1.ShowEvent = test;
}
public void test1() {
ShowlbDevTem("123"); //textBox1.Text = "123";
}

private void button1_Click(object sender, EventArgs e) {
// ShowlbDevTem("112");
}
/* public void test(string str) {
ShowlbDevTem(str); }*/ public delegate void SWTDelegate(string AddStr); //public delegate void ComsumerTextDelegate(int Index, string AddStr); public void ShowlbDevTem(string AddStr) { if (textBox1.InvokeRequired) { SWTDelegate pd = new SWTDelegate(ShowlbDevTem); textBox1.Invoke(pd, new object[] { AddStr }); } else { textBox1.Text = AddStr; //richTextBox1.AppendText(AddStr); } }
/* public void dataShow(int row, int column, string str) { row = row % 30; ShowMessage(dataGridViewX1, str, row, column);
}

delegate void ShowMessageDelegate(DataGridView dg, string message, int row, int column); private void ShowMessage(DataGridView dg, string message, int row, int column) { if (dg.InvokeRequired) { ShowMessageDelegate showMessageDelegate = ShowMessage; dg.Invoke(showMessageDelegate, new object[] { dg, message, row, column }); } else {
dg.Rows[row].Cells[column].Value = message; } } */

}}

class1中代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;
using System.Threading;using System.Windows.Forms;
namespace WindowsFormsApp12{ class Class1 { //public Action<string> ShowEvent; public void test() {
//ShowEvent("123456789");
Form1 f1 = new Form1(); f1.ShowlbDevTem("112");

}
}}

运行结果:

哎呦,卧槽

运行不报错 但是文本框中是空的,怎么办?

主窗体:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApp12{ public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) {
//CheckForIllegalCrossThreadCalls = false; Class1 cs1 = new Class1(); Thread th = new Thread(cs1.test); th.Start(); cs1.ShowEvent = test;
}
public void test1() {
ShowlbDevTem("123"); //textBox1.Text = "123";
}

private void button1_Click(object sender, EventArgs e) {
// ShowlbDevTem("112");
}
public void test(string str) {
ShowlbDevTem(str); } public delegate void SWTDelegate(string AddStr); //public delegate void ComsumerTextDelegate(int Index, string AddStr); public void ShowlbDevTem(string AddStr) { if (textBox1.InvokeRequired) { SWTDelegate pd = new SWTDelegate(ShowlbDevTem); textBox1.Invoke(pd, new object[] { AddStr }); } else { textBox1.Text = AddStr; //richTextBox1.AppendText(AddStr); } }
/* public void dataShow(int row, int column, string str) { row = row % 30; ShowMessage(dataGridViewX1, str, row, column);
}

delegate void ShowMessageDelegate(DataGridView dg, string message, int row, int column); private void ShowMessage(DataGridView dg, string message, int row, int column) { if (dg.InvokeRequired) { ShowMessageDelegate showMessageDelegate = ShowMessage; dg.Invoke(showMessageDelegate, new object[] { dg, message, row, column }); } else {
dg.Rows[row].Cells[column].Value = message; } } */

}}

类中:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;
using System.Threading;using System.Windows.Forms;
namespace WindowsFormsApp12{ class Class1 { public Action<string> ShowEvent; public void test() {
ShowEvent("123456789");
// Form1 f1 = new Form1(); //f1.ShowlbDevTem("112");

}
}}

总算可以了 

但是我有两个类,线程在class1,委托在class2回调呢?

主窗体代码不变

class1代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;
using System.Threading;using System.Windows.Forms;
namespace WindowsFormsApp12{ class Class1 { public Action<string> ShowEvent; public void test() {

// Class2 cs2 = new Class2(); // cs2.test(ShowEvent); Class2 cs2 = new Class2(); cs2.test(ShowEvent);
}



}}

class2代码

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;
using System.Threading;
namespace WindowsFormsApp12{ class Class2 { // public Action<string> ShowEvent1; public void test(Action<string> ShowEvent) {

ShowEvent("123456789");
} }}

完!!!


以上是关于C# 线程中操作窗体控件的主要内容,如果未能解决你的问题,请参考以下文章

C# winform 跨线程操作winform程序窗体

c#如何跨线程调用窗体控件

C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它

C# Winform项目中多线程环境下, 如何跨线程对Window窗体控件进行安全访问?

c#中如何跨线程调用windows控件

C#的两个控件在窗体移动。