C#如何在另一个类的线程中对Textbox内容进行修改?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#如何在另一个类的线程中对Textbox内容进行修改?相关的知识,希望对你有一定的参考价值。
WinForm是主窗体,
public class WinForm: Form
public WinServer()
InitializeComponent();
private void WinServer_Load(object sender, EventArgs e)
Receive.Instance.Start();
还有一个类Receive
public class Receive
static Receive_instance = null;
public static Receive Instance
get
if (null == _instance)
_instance = new Receive();
return _instance;
public void Start()
try
Thread th = new Thread(refresh);
th.IsBackground = true;
th.Start();
catch(Exception ex)
void refresh()
while (true)
//在这里更新TextBox的内容
这个是我的类 ,具体要怎么写?
TextBox tb=null;
public void Start(TextBox tb=null)
this.tb=tb;
//你原本的start中的其它代码
//以下内容也添加至Receive类
public delegate void textbox_delegate(string msg);
public void textbox(string msg)
if(tb==null) return;
if(tb.InvokeRequired)
textbox_delegate dt = new textbox_delegate(msg);
tb.Invoke(dt, new object[]msg);
else
tb.Text=msg;//更新textbox内容
//refresh就可以为
void refresh()
while (true)
//在这里更新TextBox的内容
string msg="hello world";
textbox(msg);
Thread.Sleep(0);
//假定winform中的textbox为txtMsg,那代码就可以写作
Receive.Instance.Start(txtMsg);追问
textbox_delegate dt = new textbox_delegate(msg);
“msg”是“变量”,但此处被当做“方法”来使用
textbox_delegate dt = new textbox_delegate(textbox);
参考技术A //自定义一个委托MyInvokeCapture miCapture = new MyInvokeCapture(UpdatePictureBoxCapture);
if (this.IsHandleCreated)
this.BeginInvoke(miDgv, cardId.ToString(), name, swipeDate, controllerName + "[" + controllerSN + "]", (int)status, statusResult, detailInfo);
/// <summary>
/// 更新文本框内容 和 刷卡用户登记的照片信息 如果非法闯入 显示为红色
/// </summary>
/// <param name="txt">需要更新的文本框控件</param>
/// <param name="contents">用户的基本信息</param>
/// <param name="pic">需要更新的PictureBox控件</param>
/// <param name="photo">照片</param>
private void UpdateTextBoxAndPicture(RichTextBox txt, string contents, PictureBox pic, object photo, long status)
txt.Text = contents;
txt.Select(0, txt.Text.Length);
if (status == 0x84) //非法闯入
txt.SelectionColor = Color.Red;
else if (status < 4) //正常通过
txt.SelectionColor = Color.Black;
else //报警通过 显示为蓝色
txt.SelectionColor = Color.Blue;
if (photo != DBNull.Value)
try
byte[] buffer = (byte[])photo;
MemoryStream ms = new MemoryStream(buffer);
ms.Read(buffer, 0, buffer.Length);
pic.Image = Image.FromStream(ms);
catch
pic.Image = null;
else
pic.Image = null;
参考技术B
你需要知道Control.InvokeRequired的用法。这个与线程操作有关。参考一个代码示例:
在你的WinForm里定义如下的一个函数:
private void SetText(string text)// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] text );
else
this.textBox1.Text = text;
在线程里如下调用这个函数:
// This event handler creates a thread that calls a// Windows Forms control in a thread-safe way.
private void setTextSafeBtn_Click(
object sender,
EventArgs e)
this.demoThread =
new Thread(new ThreadStart(this.ThreadProcSafe));
this.demoThread.Start();
// This method is executed on the worker thread and makes
// a thread-safe call on the TextBox control.
private void ThreadProcSafe()
this.SetText("This text was set safely.");
在应用程序中实现多线程的首选方式是使用 BackgroundWorker 组件。 BackgroundWorker 组件使用事件驱动模型实现多线程。 后台线程运行 DoWork 事件处理程序,而创建控件的线程运行 ProgressChanged 和 RunWorkerCompleted 事件处理程序。 可以从 ProgressChanged 和 RunWorkerCompleted 事件处理程序调用控件。
使用 BackgroundWorker 进行线程安全调用
创建一个方法,该方法用于执行您希望在后台线程中完成的工作。 不要调用由此方法中的主线程创建的控件。
创建一个方法,用于在后台工作完成后报告结果。 在此方法中可以调用主线程创建的控件。
将步骤 1 中创建的方法绑定到 BackgroundWorker 的实例的 DoWork 事件,并将步骤 2 中创建的方法绑定到同一实例的 RunWorkerCompleted 事件。
若要启动后台线程,请调用 BackgroundWorker 实例的 RunWorkerAsync 方法。
在下面的代码示例中,DoWork 事件处理程序使用 Sleep 来模拟需要花费一些时间完成的工作。 它不调用窗体的 TextBox 控件。 TextBox 控件的 Text 属性在 RunWorkerCompleted 事件处理程序中直接设置。
// This event handler starts the form's// BackgroundWorker by calling RunWorkerAsync.
//
// The Text property of the TextBox control is set
// when the BackgroundWorker raises the RunWorkerCompleted
// event.
private void setTextBackgroundWorkerBtn_Click(
object sender,
EventArgs e)
this.backgroundWorker1.RunWorkerAsync();
// This event handler sets the Text property of the TextBox
// control. It is called on the thread that created the
// TextBox control, so the call is thread-safe.
//
// BackgroundWorker is the preferred way to perform asynchronous
// operations.
private void backgroundWorker1_RunWorkerCompleted(
object sender,
RunWorkerCompletedEventArgs e)
this.textBox1.Text =
"This text was set safely by BackgroundWorker.";
参考技术C 什么叫在另一个线程啊?在线程中修改控件的值必须得用委托。 直接赋值会报错的 大哥追问
我就是想问怎么写?
追答 //定义一个委托private delegate void WriteLogHandle(string format, params object[] parms);
//输出
private void WriteLog(string format, params object[] parms)
if (控件名称.InvokeRequired)
控件名称.BeginInvoke(new WriteLogHandle(WriteLog), format, parms);
else
控件名称.AppendText(string.Format(format, parms));
private object obj = new object();
private void 线程方法(object ps)
lock (obj)//加锁
WriteLog("aaaa");//给你的控件赋值
参考技术D 添加这句就行 关闭线程间System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
以上是关于C#如何在另一个类的线程中对Textbox内容进行修改?的主要内容,如果未能解决你的问题,请参考以下文章
C# 中 一个窗体中的texbox内容显示在另一个窗体中的textbox中。如何实现
如何在C# winform 中对textbox 实现只读,并且不使其变灰,各位知道的提点下