关于UI界面winform的label值能赋值但是界面上没有变化的问题,求解

蔡徐坤 Rap 2020-06-27 12:13:37






----------------------------------------------
请教各位大神一下为什么我的一个label.text值可以赋值。代码在图里,frmMain是我的主窗体,改变UI的label值在一个派生类Client :frmMain 里面,但是程序跑到label_sn.text ="AA",这里,我的界面上的label的值没变化,但是我用断点,label_sn.text的值是"AA",但是运行的时候界面上没变化,请帮忙解决一下,想了很久,还用了网上的invoke方法SetText还是没解出来,请大神帮忙看下,感激不尽,不知道是不是因为output_async_func是异步的原因,我SetText里面把invoke换成BeginInvoke还是不行。。。。求解,感激不尽。
-----------------------------------------------------
...全文
3008 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
蔡徐坤 Rap 2020-06-28
  • 打赏
  • 举报
回复
引用 14 楼 icoolno1 的回复:
[quote=引用 11 楼 lubianxiaocaiji 的回复:] [quote=引用 10 楼 icoolno1 的回复:] 代码看不全,不好评论。可能值设了,但界面没有重绘。多数可能主线程阻塞了,收不到消息循环中的PAINT消息,在设置完属性后,调用一下Update()方法试试。
代码全了,我已经把他全贴上去了。 ----------------------------------------------------- public partial class frmMain : Form { public frmMain() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } public static string cygwin_cmd = @"C:\cygwin64\Cygwin.bat"; private static Thread Client_t = null; public static Client client = null; public static Client server = null; public static StringBuilder stdout = null; public static StreamWriter stdin = null; public delegate void SetTextCallback(string text); public void setText(string text) { if (this.label_sn.InvokeRequired) { SetTextCallback s = new SetTextCallback(setText); this.label_sn. Invoke(s, new object[] { text }); } else { this.label_sn.Text = text; } } private void Form1_Load(object sender, EventArgs e) { label_sn.Text = "BB"; client = new Client(); client.Run_Client(); } public void Run_Client() { var Client_t = new Thread(new ThreadStart(client_thread_func)); Client_t.IsBackground = true; Client_t.Start(); } public void client_thread_func() { var proc = new Process(); proc.StartInfo.FileName = cygwin_cmd; proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; stdout = new StringBuilder(); proc.OutputDataReceived += new DataReceivedEventHandler(output_async_func); proc.Start(); stdin = proc.StandardInput; proc.StandardInput.Flush(); proc.BeginOutputReadLine(); proc.WaitForExit(); proc.EnableRaisingEvents = true; proc.Dispose(); } public virtual void output_async_func(object sender, DataReceivedEventArgs outLine) { if (!String.IsNullOrEmpty(outLine.Data)) { stdout.Append(Environment.NewLine + DateTime.Now.ToString("yyyy-HH-dd HH:mm:ss") + outLine.Data); } } } public class Client : frmMain { public Client() { } public override void output_async_func(object sender, DataReceivedEventArgs outLine) { base.output_async_func(sender, outLine); if (!string.IsNullOrEmpty(outLine.Data)) { label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。 } } } ----------------------------------- 在Form1_Load的时候label_sn.Text = "BB"; 到了这里 label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。[/quote] 看了一下,程序写错了,你更新的是另一个没有显示出来的实例的 label_sn,那个窗口又没显示出来,所以看不到结果。你把fromload改成这样试试:

 private void Form1_Load(object sender, EventArgs e)
            {
                label_sn.Text = "BB";

                
                this.Run_Client();
            }
[/quote] 感谢,你的思路对的,按照你说的改了一下确实可以,感谢大佬。
datafansbj 2020-06-28
  • 打赏
  • 举报
回复 1
多半是UI线程阻塞了,没有及时 update。Windows 界面发生变化(重绘)是有条件的,即必须响应系统的重绘消息。例如:
for (int i = 0; i < 100; i++)
{
label1.Text = i.ToString();
}

label1 不会显示 100 次 i 的值,只能显示最后的值(即 99),因为循环体内没有能够响应界面刷新的机会,循环结束后才能响应重绘消息。你在调试状态时,代码执行到断点会暂停下来,这时系统就可以响应重绘消息了,所以你调试时是能刷新界面的。
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
方法一直接label_sn.Text ="AA",运行到那里根本没变化,方法二SetText是网上的方法,但是还是没变化,求解。我已经把label_sn的属性弄成public,还是不行。求大神解决。
八爻老骥 2020-06-27
  • 打赏
  • 举报
回复
引用 11 楼 lubianxiaocaiji 的回复:
[quote=引用 10 楼 icoolno1 的回复:]
代码看不全,不好评论。可能值设了,但界面没有重绘。多数可能主线程阻塞了,收不到消息循环中的PAINT消息,在设置完属性后,调用一下Update()方法试试。


代码全了,我已经把他全贴上去了。
-----------------------------------------------------

public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}

public static string cygwin_cmd = @"C:\cygwin64\Cygwin.bat";

private static Thread Client_t = null;
public static Client client = null;
public static Client server = null;

public static StringBuilder stdout = null;
public static StreamWriter stdin = null;

public delegate void SetTextCallback(string text);
public void setText(string text)
{
if (this.label_sn.InvokeRequired)
{
SetTextCallback s = new SetTextCallback(setText);
this.label_sn. Invoke(s, new object[] { text });
}
else
{
this.label_sn.Text = text;
}
}

private void Form1_Load(object sender, EventArgs e)
{
label_sn.Text = "BB";

client = new Client();
client.Run_Client();
}

public void Run_Client()
{
var Client_t = new Thread(new ThreadStart(client_thread_func));
Client_t.IsBackground = true;
Client_t.Start();
}

public void client_thread_func()
{
var proc = new Process();
proc.StartInfo.FileName = cygwin_cmd;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
stdout = new StringBuilder();
proc.OutputDataReceived += new DataReceivedEventHandler(output_async_func);
proc.Start();
stdin = proc.StandardInput;
proc.StandardInput.Flush();
proc.BeginOutputReadLine();
proc.WaitForExit();
proc.EnableRaisingEvents = true;
proc.Dispose();
}

public virtual void output_async_func(object sender, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
stdout.Append(Environment.NewLine + DateTime.Now.ToString("yyyy-HH-dd HH:mm:ss")
+ outLine.Data);
}
}
}

public class Client : frmMain
{
public Client()
{

}

public override void output_async_func(object sender, DataReceivedEventArgs outLine)
{
base.output_async_func(sender, outLine);
if (!string.IsNullOrEmpty(outLine.Data))
{
label_sn.Text = "AA"; //方法1
setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。
}
}
}
-----------------------------------
在Form1_Load的时候label_sn.Text = "BB";
到了这里
label_sn.Text = "AA"; //方法1
setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。[/quote]

看了一下,程序写错了,你更新的是另一个没有显示出来的实例的 label_sn,那个窗口又没显示出来,所以看不到结果。你把fromload改成这样试试:

private void Form1_Load(object sender, EventArgs e)
{
label_sn.Text = "BB";


this.Run_Client();
}
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
引用 7 楼 exception92 的回复:
setText里边的while循环处理是个什么情况
public partial class frmMain : Form { public frmMain() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } public static string cygwin_cmd = @"C:\cygwin64\Cygwin.bat"; private static Thread Client_t = null; public static Client client = null; public static Client server = null; public static StringBuilder stdout = null; public static StreamWriter stdin = null; public delegate void SetTextCallback(string text); public void setText(string text) { if (this.label_sn.InvokeRequired) { SetTextCallback s = new SetTextCallback(setText); this.label_sn. Invoke(s, new object[] { text }); } else { this.label_sn.Text = text; } } private void Form1_Load(object sender, EventArgs e) { label_sn.Text = "BB"; client = new Client(); client.Run_Client(); } public void Run_Client() { var Client_t = new Thread(new ThreadStart(client_thread_func)); Client_t.IsBackground = true; Client_t.Start(); } public void client_thread_func() { var proc = new Process(); proc.StartInfo.FileName = cygwin_cmd; proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; stdout = new StringBuilder(); proc.OutputDataReceived += new DataReceivedEventHandler(output_async_func); proc.Start(); stdin = proc.StandardInput; proc.StandardInput.Flush(); proc.BeginOutputReadLine(); proc.WaitForExit(); proc.EnableRaisingEvents = true; proc.Dispose(); } public virtual void output_async_func(object sender, DataReceivedEventArgs outLine) { if (!String.IsNullOrEmpty(outLine.Data)) { stdout.Append(Environment.NewLine + DateTime.Now.ToString("yyyy-HH-dd HH:mm:ss") + outLine.Data); } } } public class Client : frmMain { public Client() { } public override void output_async_func(object sender, DataReceivedEventArgs outLine) { base.output_async_func(sender, outLine); if (!string.IsNullOrEmpty(outLine.Data)) { label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。 } } } ----------------------------------- 在Form1_Load的时候label_sn.Text = "BB"; 到了这里 label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。 帮忙看下
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
引用 4 楼 以专业开发人员为伍 的回复:
程序逻辑太曲折、太繁复,有点超出了我的极限。 你可以先从最简单最“笨”的语句写起,每一次改进一点点,每修改1、2行代码就测试,如果遇到bug就回滚到上一次测试点。找到自己的问题。
public partial class frmMain : Form { public frmMain() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } public static string cygwin_cmd = @"C:\cygwin64\Cygwin.bat"; private static Thread Client_t = null; public static Client client = null; public static Client server = null; public static StringBuilder stdout = null; public static StreamWriter stdin = null; public delegate void SetTextCallback(string text); public void setText(string text) { if (this.label_sn.InvokeRequired) { SetTextCallback s = new SetTextCallback(setText); this.label_sn. Invoke(s, new object[] { text }); } else { this.label_sn.Text = text; } } private void Form1_Load(object sender, EventArgs e) { label_sn.Text = "BB"; client = new Client(); client.Run_Client(); } public void Run_Client() { var Client_t = new Thread(new ThreadStart(client_thread_func)); Client_t.IsBackground = true; Client_t.Start(); } public void client_thread_func() { var proc = new Process(); proc.StartInfo.FileName = cygwin_cmd; proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; stdout = new StringBuilder(); proc.OutputDataReceived += new DataReceivedEventHandler(output_async_func); proc.Start(); stdin = proc.StandardInput; proc.StandardInput.Flush(); proc.BeginOutputReadLine(); proc.WaitForExit(); proc.EnableRaisingEvents = true; proc.Dispose(); } public virtual void output_async_func(object sender, DataReceivedEventArgs outLine) { if (!String.IsNullOrEmpty(outLine.Data)) { stdout.Append(Environment.NewLine + DateTime.Now.ToString("yyyy-HH-dd HH:mm:ss") + outLine.Data); } } } public class Client : frmMain { public Client() { } public override void output_async_func(object sender, DataReceivedEventArgs outLine) { base.output_async_func(sender, outLine); if (!string.IsNullOrEmpty(outLine.Data)) { label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。 } } } ----------------------------------- 在Form1_Load的时候label_sn.Text = "BB"; 到了这里 label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。 帮忙看下。 -------------------------------------------------------
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
引用 10 楼 icoolno1 的回复:
代码看不全,不好评论。可能值设了,但界面没有重绘。多数可能主线程阻塞了,收不到消息循环中的PAINT消息,在设置完属性后,调用一下Update()方法试试。
代码全了,我已经把他全贴上去了。 ----------------------------------------------------- public partial class frmMain : Form { public frmMain() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } public static string cygwin_cmd = @"C:\cygwin64\Cygwin.bat"; private static Thread Client_t = null; public static Client client = null; public static Client server = null; public static StringBuilder stdout = null; public static StreamWriter stdin = null; public delegate void SetTextCallback(string text); public void setText(string text) { if (this.label_sn.InvokeRequired) { SetTextCallback s = new SetTextCallback(setText); this.label_sn. Invoke(s, new object[] { text }); } else { this.label_sn.Text = text; } } private void Form1_Load(object sender, EventArgs e) { label_sn.Text = "BB"; client = new Client(); client.Run_Client(); } public void Run_Client() { var Client_t = new Thread(new ThreadStart(client_thread_func)); Client_t.IsBackground = true; Client_t.Start(); } public void client_thread_func() { var proc = new Process(); proc.StartInfo.FileName = cygwin_cmd; proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; stdout = new StringBuilder(); proc.OutputDataReceived += new DataReceivedEventHandler(output_async_func); proc.Start(); stdin = proc.StandardInput; proc.StandardInput.Flush(); proc.BeginOutputReadLine(); proc.WaitForExit(); proc.EnableRaisingEvents = true; proc.Dispose(); } public virtual void output_async_func(object sender, DataReceivedEventArgs outLine) { if (!String.IsNullOrEmpty(outLine.Data)) { stdout.Append(Environment.NewLine + DateTime.Now.ToString("yyyy-HH-dd HH:mm:ss") + outLine.Data); } } } public class Client : frmMain { public Client() { } public override void output_async_func(object sender, DataReceivedEventArgs outLine) { base.output_async_func(sender, outLine); if (!string.IsNullOrEmpty(outLine.Data)) { label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。 } } } ----------------------------------- 在Form1_Load的时候label_sn.Text = "BB"; 到了这里 label_sn.Text = "AA"; //方法1 setText("AA"); //方法2 我1和2 运行到这里label_sn的值变成AA,但是界面上没变化。
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
麻烦大神帮一下。在线等啊。。
八爻老骥 2020-06-27
  • 打赏
  • 举报
回复
代码看不全,不好评论。可能值设了,但界面没有重绘。多数可能主线程阻塞了,收不到消息循环中的PAINT消息,在设置完属性后,调用一下Update()方法试试。
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
各位路过的大神帮忙一下,感激不尽。不知道为啥刷新不了,整份代码我没加延时,实在想不出法子,在线等... 有没有办法可以模拟一个按钮事件来改变label.text的值但是不需要按下按钮,因为工厂操作员不可能每次点按钮来看测试结果。 public void button1_Click(object sender, EventArgs e) { label_sn.Text = SN; } ----------------------------------- 点击按钮事件可以生效,有没有大神可以给我简单写一下,模拟按钮事件,但是不需要鼠标点击按钮就能触发。可能我想多了。。。因为实在想不出办法了,在线等各路大神支招。。 ---------------------------------- 小白修炼路上,请各位指点,至此,端午安康,Thanks -----------------------------------------
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
引用 7 楼 exception92 的回复:
setText里边的while循环处理是个什么情况
----------------------------------------- 版主,去掉也一样。帮忙小白解决一下,项目紧急,新人顶不住啊,准备引咎辞职。。。 public void setText(string text) { if (this.label_sn.InvokeRequired) { SetTextCallback s = new SetTextCallback(setText); this.label_sn. Invoke(s, new object[] { text }); } else { this.label_sn.Text = text; } }
exception92 2020-06-27
  • 打赏
  • 举报
回复
setText里边的while循环处理是个什么情况
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
引用 5 楼 以专业开发人员为伍 的回复:
简单地“扫”了几秒钟,感觉有把简单问题弄复杂10倍的“过分技术化”倾向,估计是之前跟“老程序员”学偏了。
---------------------------------- 大神帮忙看一下,我已经是想不出了,两个class类,frmMain和Client : frmMain,,output_async_func重写了,因为输出的每行内容需要截取字符串信息来判断,所以用override,base.output_async_func,,我已经是按照你说的很简单一步步来, 方法1我直接label_sn.text = "XX",发现界面没变化,但是label_sn的值确实改变了,就是界面上没变化。 方法2用了网上的SetText("XX")也是不行。 -------------------------------------- 试了很多分方法 一)加了这个 CheckForIllegalCrossThreadCalls = false;这个不行。 二)委托也不行。 public delegate void SetTextCallback(string text); public void setText(string text) { if (this.label_sn.InvokeRequired) { while (!this .label_sn.IsHandleCreated) { if (this.label_sn.Disposing || this.label_sn.IsDisposed) { return; } } SetTextCallback s = new SetTextCallback(setText); this.label_sn. Invoke(s, new object[] { text }); } else { this.label_sn.Text = text; } }
  • 打赏
  • 举报
回复
简单地“扫”了几秒钟,感觉有把简单问题弄复杂10倍的“过分技术化”倾向,估计是之前跟“老程序员”学偏了。
  • 打赏
  • 举报
回复
程序逻辑太曲折、太繁复,有点超出了我的极限。

你可以先从最简单最“笨”的语句写起,每一次改进一点点,每修改1、2行代码就测试,如果遇到bug就回滚到上一次测试点。找到自己的问题。
蔡徐坤 Rap 2020-06-27
  • 打赏
  • 举报
回复
没人啊。解答一下

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧