秒表改变c#中的按钮文字

时间:2013-05-21 18:43:05

标签: c# arrays multithreading timer stopwatch

基本上,我的表单中有多个按钮,我希望它在按钮中显示一个秒表。按下按钮时的文本。 (按钮被修改为切换按钮。)并在按钮关闭时停止并重置音调。看起来很简单,但因为我有多个按钮可以按任意顺序按下,而且我对线程没有任何了解,这似乎比我想象的要困难得多。

我的原始意图是拥有一个每秒不断运行的功能,并且只有在使用此代码按下按钮时才会对交互者进行交互:

public void Jogger()//purpose is to step up time[0] every second only when a button is on.
    {
        while (true)
        {
            for (int i = 0; i < 16; i++)
            {
                if (btnstat[i])
                    time[i]++;
            }
            Thread.Sleep(1000);
        }
    }

问题是,我不知道线程,所以当我调用该函数时,它只是这样做了。

无论哪种方式,一旦调用它,我所做的就是调用我的更新函数来更新所有按钮,包括button.Text,它显示时间[0]; (围绕按钮构建的数组)

他们是一个更好的方法,这不会导致如此多的CPU使用和/或只是工作?

感谢您的帮助! -John Ivey

3 个答案:

答案 0 :(得分:0)

Application.DoEvents()为简单起见放在循环中。 。但建议开始倾斜threading。您将学习如何启动线程以及如何使跨线程安全调用 接下来的简单就是使用backgroundworker。看这个http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

ok这里也是你想要的线程解决方案。测试过了。作为一个停止变量我用Tag。但你可以继承按钮来制作状态按钮。这是更清晰的方式。 以下代码将使用每个按钮一个线程。所以你应该在一个线程中使它成为更好的解决方案。您可以修改此代码以在一个线程内执行所有检查。为此你启动线程一旦可以为每个按钮附加dinamically计数功能委托,或者你可以之前传递按钮。用一个词来说,有不止一种方法可以做到这一点。祝你好运

this.button1.Click += new System.EventHandler(this.button_Click);
this.button2.Click += new System.EventHandler(this.button_Click);
...and so on
  private void button_Click(object sender, EventArgs e)
        {
           Thread x= new Thread(new ParameterizedThreadStart(Jogger2));
            x.Start(sender);

        }


        private void button_Click(object sender, EventArgs e)
    {
        Button mybtn=sender as Button;
        if((string)mybtn.Tag=="start"){
            mybtn.Tag ="";
            return;
         }
        mybtn.Tag = "start";
       Thread x= new Thread(new ParameterizedThreadStart(Jogger2));
        x.Start(sender);

    }


    private bool  setResult(object obj,string text)
    { 
        if (this.textBox1.InvokeRequired)
        {
            Func<Button,string, bool > d = new Func<Button,string,bool >(setResult);
            return (bool)this.Invoke(d,obj,text);

        }
        else
        {
            Button btn=obj  as Button;

            if (btn != null)
            {
                btn.Text = text;
                if ((string)btn.Tag !="start") return false;
            }
            return true;
        }
    }
    private void Jogger2(object mybtn)
    {
        int ii = 0; 
        while (true)
        {
            Thread.Sleep(1000);
                //replace with your code
                ii += 1;
                if (!setResult(mybtn, ii.ToString())) break; 

        }

    }

答案 1 :(得分:0)

假设您使用带有属性Button = Appearence的复选框,在CheckedChanged的事件处理程序中:

private void CheckBoxCheckedChanged(object sender, EventArgs e)
{
    CheckBox checkBox = (CheckBox) sender;

    if (checkBox.Checked)
    {
        Timer timer = new Timer {Interval = 1000};
        timer.Tick += Jogger;
        timer.Start();
        timer.Tag = new CheckboxCounter {CheckBox = checkBox, Time = 0};
        checkBox.Tag = timer;
    }
    else
    {
        Timer timer = checkBox.Tag as Timer;
        if (timer != null)
        {
            timer.Tag = null;
            timer.Stop();
            timer.Dispose();
            checkBox.Tag = null;
        }
    }
}

更改您的慢跑功能:

private void Jogger(object a_sender, EventArgs a_eventArgs)
{
    Timer timer = (Timer) a_sender;
    CheckboxCounter data = (CheckboxCounter)timer.Tag;
    data.Time++;
    data.CheckBox.Text = data.Time.ToString();
}

您还需要一些简单的类来存储复选框和当前时间:

class CheckboxCounter
{
    public CheckBox CheckBox;

    public int Time;
}

然后你可以添加任意数量的复选框,只需将事件CheckedChanged设置为CheckBoxCheckedChanged。

答案 2 :(得分:0)

试一试。重新构建或运行后,您应该在ToolBox顶部使用新的“ButtonTimer”。在表单上删除一对,运行它,看看单击它们时会发生什么。右键单击它们以“重置”它们:

public class ButtonTimer : CheckBox
{

    private System.Windows.Forms.Timer Tmr = new System.Windows.Forms.Timer();
    private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();

    public ButtonTimer()
    {
        this.Tmr.Interval = 500;
        this.Tmr.Tick += new EventHandler(tmr_Tick);
        this.Appearance = System.Windows.Forms.Appearance.Button;
        this.CheckedChanged += new EventHandler(ButtonTimer_CheckedChanged);

        ContextMenuStrip cms = new ContextMenuStrip();
        ToolStripItem tsi = cms.Items.Add("Reset");
        tsi.Click += new EventHandler(tsi_Click);
        this.ContextMenuStrip = cms;
    }

    protected override void OnLayout(LayoutEventArgs levent)
    {
        base.OnLayout(levent);
        this.Text = TimeSpan.Zero.ToString(@"hh\:mm\:ss");
    }

    private void ButtonTimer_CheckedChanged(object sender, EventArgs e)
    {
        if (this.Checked)
        {
            this.SW.Start();
            this.Tmr.Start();
        }
        else
        {
            this.SW.Stop();
            this.Tmr.Stop();
        }
    }

    private void tmr_Tick(object sender, EventArgs e)
    {
        this.UpdateTime();
    }

    private void UpdateTime()
    {
        this.Text = this.SW.Elapsed.ToString(@"hh\:mm\:ss");
    }

    private void tsi_Click(object sender, EventArgs e)
    {
        if (this.SW.IsRunning)
        {
            SW.Restart();
        }
        else
        {
            SW.Reset();
        }
        this.UpdateTime();
    }

}