为什么我第一次尝试更改此代码中的按钮文本不起作用,而第三次尝试却起作用?
我的用户在串行端口连接时必须等待几秒钟。之后,我想提醒他他已经连接了(第二次尝试可能会导致问题)。
我想让他知道一切都很好,这样他就不会想到“呃”并点击两次。
失败。文本更改永远不会出现。
好的,为什么按钮文本的第三个更改有效,但第一个却不起作用?不知道第二个行不行。
/***********************************************************************
* Button: Connect Port *
***********************************************************************/
private void TheConnectPortButton_Click(object sender, EventArgs e)
{
string OldText = TheConnectPortButton.Text;
TheConnectPortButton.Text = "Busy, Please Wait"; /////// This never happens
ButtonBoss.ButtonHandler_ConnectPort();
TheConnectPortButton.Text = OldText; /////// Not sure if this happens
if (aUartSemaphoreThatTells.IfWeHaveConnectedToAPort == (int)aValueWhichIndicatesThat.YesWeHaveAGoodPortConnected)
{
TheConnectPortButton.Text = "Connected"; /////// This one does happen
}
}
aUartSemaphoreThatTells.IfWeHaveConnectedToAPort
也被 ButtonBoss
例程使用,以确保他不会与其他按钮例程一起第二次连接(例如,确保我们在 Tx/Rx 或其他任何内容之前就已连接)。
我尝试在例程返回后更改代码,看起来像这样......
if (aUartSemaphoreThatTells.IfWeHaveConnectedToAPort == (int)aValueWhichIndicatesThat.YesWeHaveAGoodPortConnected)
{
TheConnectPortButton.Text = "Connected";
}
else
{
TheConnectPortButton.Text = OldText;
}
...我仍然得到相同的结果。
我的猜测(仅此而已)是线程以某种方式参与了所有这一切,并且串行端口例程通过一些我目前没有正确遵循的卷积来胜过按钮文本更改例程。
问题:在连接内容占用系统之前,我需要做什么才能更改文本?
(如果发生了这种情况)
问题 2:如果我不能做到这一点,我想我已经读过有关“灰色”按钮的内容,或者,我相信我在某个地方看到我实际上可以让按钮在用户眼前消失这样他就不能再点击它了。欢迎提供示例代码的链接。
最佳答案
问题是您正在从同一个事件处理程序中执行所有操作,因此按钮没有时间更新(重绘)。您可以调用 Application.DoEvents();
方法,但这根本不是一个好主意,请阅读 Use of Application.DoEvents()
我认为通常您需要将一项耗时的任务推送到一个单独的线程中,从中获取进度报告并更新您的 GUI。有很多方法可以创建“工作”线程并从中获得一些响应。例如,使用 BackgroundWorker Class :
public partial class Form1 : Form
{
public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e)
{
BackgroundWorker w = new BackgroundWorker();
w.WorkerReportsProgress = true;
w.DoWork += new DoWorkEventHandler(w_DoWork);
w.ProgressChanged += new ProgressChangedEventHandler(w_ProgressChanged);
w.RunWorkerCompleted += new RunWorkerCompletedEventHandler(w_RunWorkerCompleted);
w.RunWorkerAsync();
button1.Text = "Started";
}
//may influence GUI, as this event handler is run on the GUI thread
void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.Text = "Job is done";
}
//may influence GUI, as this event handler is run on the GUI thread
void w_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
button1.Text = e.ProgressPercentage.ToString();
}
//runs in the worker thread...should do the actual job
//may influence GUI through `ReportProgress`
//or through `Invoke` method
void w_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(500);
worker.ReportProgress(10 * i);
}
}
}
或者您可以使用Task Class :
public partial class Form1 : Form
{
public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e)
{
new Task(DoTask).Start();
}
void DoTask()
{
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(500);
//here you need to update GUI through `Invoke` method
//as the GUI may only be influenced from the the thread,
//where it's created
this.Invoke(new Action<int>((j) =>
{
button1.Text = j.ToString();
}), 10 * i);
}
}
}
关于c# - 按钮文字,不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14249057/