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的内容



这个是我的类 ,具体要怎么写?

//recevie类里加几行代码以取得那个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 实现只读,并且不使其变灰,各位知道的提点下

C#在其它类的线程工更新winForm中的textbox内容?

C#关于定时器和多线程中对控件的操作以及界面假死的现象。

在C#里如何让控件textbox中的内容居中显示呢?

c#程序,textbox如何设置文本居中显示?如何按行读取文本文件内容?