【问题标题】:Change a button color on button click temporarily in C#在 C# 中临时更改按钮单击时的按钮颜色
【发布时间】:2012-08-02 04:32:49
【问题描述】:

这是 Win 表格

单击按钮时我想暂时更改按钮的颜色,只说 1 秒钟,然后按钮颜色应该恢复到以前的颜色。我为此使用了 lambda 表达式和计时器。

    private void btn_Read_Click(object sender, EventArgs e)
    {
            System.Windows.Forms.Timer t1 = new System.Windows.Forms.Timer();
            t1.Interval = 1000;
            t1.Tick += (src, ee) => 
            {
                btn_Read.BackColor = Color.Transparent; t1.Stop();
            };
            t1.Start();
            btn_Read.BackColor = Color.YellowGreen;
            lvwMessages.Items.Clear();
            string strcommand = "AT+CMGL=\"ALL\"";
            objShortMessageCollection = ReadSMS(strcommand); // Line wher I am reading messages from the port
            foreach (ShortMessage msg in objShortMessageCollection)
            {
                ListViewItem item = new ListViewItem(new string[] { msg.Sender, msg.Message, msg.Sent, msg.Index });
                item.Tag = msg;
                lvwMessages.Items.Insert(0, item);
            }
            if (lvwMessages.Items.Count == 0)
            {
                status_other.Visible = true;
                status_other.Text = "No messages";
                lbl_total.Text = "Total: 0";
                System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
                timer1.Interval = 2000;
                timer1.Tick += (source, ex) => { status_other.Visible = false; timer1.Stop(); };
                timer1.Start();
            }
            else
            {
                status_other.Visible = false;
                chk_selectmsg.Visible = true;
                btn_delete.Visible = true;
                lbl_total.Text = "Total: " + lvwMessages.Items.Count.ToString(); ;
            }
        }

稍后在此代码中,我正在从串行端口读取数据,显示它等。问题是当我单击按钮时按钮颜色不会改变。这需要一些时间,并且不会给我想要的感觉。有时甚至不改变颜色。可能是什么原因?

【问题讨论】:

  • 也许在 mouseDown 事件中试试这个?也许在创建计时器之前使用 'btn_Read.BackColor =' 语句?
  • 您是否在 btn_Read_Click 方法中进行串行端口读取和其他需要时间的操作?如果是这样,它将解释您所看到的
  • @ekholm :是的,但这不会阻止我的用户界面,获取数据大约需要 500 毫秒
  • @UtkarshSinha:没有区别。结果也一样
  • @Cdeez:好的,为了确定时间,我会在 btn_Read_Click 退出时将一些时间戳写入控制台或日志文件,并在 Tick 事件处理程序中。

标签: c# button lambda serial-port background-color


【解决方案1】:

一个简单的解决方案是使用鼠标悬停事件和鼠标离开事件

这样使用:

    private void btn_Read_MouseHover(object sender, EventArgs e)
    {
        btn_Read.BackColor = Color.AliceBlue;
    }

    private void btn_Read_MouseLeave(object sender, EventArgs e)
    {
        btn_Read.BackColor = Color.AntiqueWhite;
    }

这不需要对您的代码进行任何更改,并且肯定会为您提供功能。看看有没有帮助!

【讨论】:

  • 如果用户使用键盘而不是鼠标来按下按钮怎么办?
【解决方案2】:

您应该避免在 UI 线程上编写工作密集型代码

要获得所需的效果,请将 UI 代码与执行工作的代码分开...

当按钮被点击时,改变它的外观并启动一些后台任务(线程池、后台工作者等)来完成这项工作

请注意,您只能从创建控件的线程与控件交互,因此要显示数据或与 UI 交互,您必须调用 UI 线程(请参阅Control.Invoke(...)

如果您有很多这样的 UI 重置内容,您应该考虑在表单上设置一个计时器,以每隔 200 毫秒检查一次是否有需要重置/完成的内容

您可以使用带有元组 (Datetime,delegate) 的排序列表,一旦时间到了,这些元组就会被执行和删除...

【讨论】:

    【解决方案3】:

    在线程中编写其余代码并触发该线程。这将使您的 UI 响应并为您提供所需的按钮输出。或在更改颜色后使用 btnedit.Refresh() 强制按钮重绘自身

    【讨论】: