C#如何在另一个类的线程中对Textbox内容进行修改? 20

WinForm是主窗体,publicclassWinForm:Form{publicWinServer(){InitializeComponent();}privatev... 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的内容
}
}
}
这个是我的类 ,具体要怎么写?
展开
 我来答
syht2000
高粉答主

推荐于2017-11-26 · 关注我不会让你失望
知道大有可为答主
回答量:3万
采纳率:79%
帮助的人:1.4亿
展开全部
//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);
斯内科Snake
2014-03-07 · TA获得超过523个赞
知道小有建树答主
回答量:707
采纳率:50%
帮助的人:243万
展开全部
//自定义一个委托
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;
            }
        }
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友862b31c
2014-03-07 · TA获得超过1529个赞
知道小有建树答主
回答量:1045
采纳率:100%
帮助的人:820万
展开全部

你需要知道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.";
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
丶风清云淡丨so
2014-03-07 · TA获得超过156个赞
知道小有建树答主
回答量:192
采纳率:0%
帮助的人:151万
展开全部
什么叫在另一个线程啊?在线程中修改控件的值必须得用委托。 直接赋值会报错的 大哥
追问
我就是想问怎么写?
追答
 //定义一个委托
 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");//给你的控件赋值

                         }

        }

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
llb0828
2014-03-07
知道答主
回答量:43
采纳率:0%
帮助的人:15.5万
展开全部
添加这句就行 关闭线程间System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式