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);

温馨提示:内容为网友见解,仅供参考
第1个回答  2014-03-07
//自定义一个委托
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;
            }
        }

第2个回答  2014-03-07

你需要知道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.";
}

第3个回答  2014-03-07
什么叫在另一个线程啊?在线程中修改控件的值必须得用委托。 直接赋值会报错的 大哥追问

我就是想问怎么写?

追答 //定义一个委托
 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");//给你的控件赋值

                         }

        }

第4个回答  2014-03-07
添加这句就行 关闭线程间System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

C#如何在另一个类的线程中对Textbox内容进行修改?
\/\/recevie类里加几行代码以取得那个textboxTextBox 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....

C#如何在另一个类的线程中对Textbox内容进行修改?
delegate void MethodInvoker(string text);private void SetText(string p){ if (this.InvokeRequired){ MethodInvoker invoker=new MethodInvoker(this.SetText);this.Invoke(invoker, p);return;} this.textBox1.Text = p;}

C#中如何通过点击一个窗体上button,给另一窗体上的textbox赋值
form2.ShowDialog(); this.textBox1.Text= form2.Str; } }Form2的代码: public partial class Form2 : Form { privatestring str; public string Str { get{ return this.str;} set{ this.str = value;} } privateForm1 form1; publicForm2() ...

C#在其它类的线程工更新winForm中的textbox内容?
首先你应该把Mainform里的TextBox对象(假设叫做textBox1)保存在TCPServer.Instance里;其次由于是后台线程,所以不能直接对textBox1的text赋值,应该这样:void listenerProc(){ while (true){ textBox1.Invoke( new EventHandler( delegate{ textBox1.Text = "xxxxx"; } ) );} } ...

C#怎么在别的Class修改Form上的textbox
你改了这个对象里面的textBox, 和其他对象里的没有关系。再者,static也不是这样用的,别乱用。你可以在 Form1类里面定义个 静态变量 public static TextBox MyTextBox;在Form1类初始化时,给 MyTextBox=this.textBoxORTreceive;这样在其他类中你可以 Form1.MyTextBox来操作它 ...

C# 另一个类中 修改主窗体的Text属性
把那个窗体的textbox属性中有一个private改成public ,在另外的类中 实例化一次就可以调用了 。绝对可以。

c# 跨线程 跨类改变控件text值
不能直接跨线程访问控件的,需要用到委托,用如下方法就可以了,另外给你一个类,里面封装了一些常用方法可以使用。delegate void SetTextDelegate(Control Ctrl, string Text);\/\/\/ \/\/\/ 跨线程设置控件Text\/\/\/ \/\/\/ 待设置的控件\/\/\/ Textpublic static void SetText(Control Ctrl, string Text){ ...

C# 跨线程调用TextBox方法浅析
首先来看下面代码:主线程:delegate void SetTextCallback(string text);private void SetText(string text){if (this.textBox1.InvokeRequired){SetTextCallback d = new SetTextCallback(SetText);this.Invoke(d, new object[] { text });}else{this.textBox1.Text = text;}}private void...

C# winform 在一个窗体中如何设置另一个窗体的TextBox的值
首先介绍最粗暴的方法,修改控件的访问修饰符。(不建议使用此法)public System.Windows.Forms.TextBox textBox1;在调用时就能直接访问 Form1 frm = new Form1();frm.textBox1.Text = "方法1";frm.Show();方法2是通过构造函数\/指定公开方法传入,然后为对应控件赋值。public Form2(string text){...

C# 我要在一个类里面更改窗口里的textbox的内容,请问怎么实现??
在类里添加个方法 class test { public static void ChangeText(TextBox textbox,string str){ textbox.Text=str;} } test.ChangeText(textbox的ID,要改变的内容);

相似回答