Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# c语言中的秒表更改按钮文本#_C#_Arrays_Multithreading_Timer_Stopwatch - Fatal编程技术网

C# c语言中的秒表更改按钮文本#

C# c语言中的秒表更改按钮文本#,c#,arrays,multithreading,timer,stopwatch,C#,Arrays,Multithreading,Timer,Stopwatch,基本上,我的表单中有多个按钮,我想在按钮中显示秒表。按下按钮时显示文本。(按钮修改为切换按钮。)以及在按钮关闭时停止并重置定时器。看起来很简单,但因为我有多个按钮,可以按任何顺序按下,而且我对线程一无所知,所以这似乎比我想象的要困难得多 我最初的目的是要有一个功能,该功能每秒钟持续运行一次,并且仅当按下按钮时,才使用以下代码对interager进行交互: public void Jogger()//purpose is to step up time[0] every second only w

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

我最初的目的是要有一个功能,该功能每秒钟持续运行一次,并且仅当按下按钮时,才使用以下代码对interager进行交互:

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);
        }
    }
public void Jogger()//目的是仅当按钮打开时每秒增加时间[0]。
{
while(true)
{
对于(int i=0;i<16;i++)
{
if(btnstat[i])
时间[i]++;
}
睡眠(1000);
}
}
问题是,我不知道线程,所以当我调用该函数时,它只能执行此操作

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

这是一种更好的方法,不会导致太多CPU使用和/或只是工作吗

谢谢你的帮助! -John Ivey

Application.DoEvents()
为简单起见,将其放入循环中。但建议开始倾斜
线程
。您将学习如何启动线程以及如何进行跨线程安全调用
下一个简单的方法是使用
backgroundworker
。看这个

好的,这是你想要的线程解决方案。也测试过了。作为停止变量,我使用Tag。但你可以继承按钮,使状态按钮。这是更清楚的方式及以下代码将为每个按钮使用一个线程。因此,您应该将其放在一个线程中,使其成为更好的解决方案。您可以修改此代码以在一个线程内执行所有检查。为此,您可以启动一次线程,使每个按钮都可以附加数字计数功能的委托,也可以在此之前传递按钮。有一个词,就有不止一种方法。祝你好运

this.button1.Click+=newsystem.EventHandler(this.button\u Click);
this.button2.Click+=新系统.EventHandler(this.button\u Click);
等等
私有无效按钮\u单击(对象发送者,事件参数e)
{
线程x=新线程(新的参数化线程启动(Jogger2));
x、 启动(发送方);
}
私有无效按钮\u单击(对象发送者,事件参数e)
{
Button mybtn=发送方为按钮;
如果((字符串)mybtn.Tag==“开始”){
mybtn.Tag=“”;
返回;
}
mybtn.Tag=“开始”;
线程x=新线程(新的参数化线程启动(Jogger2));
x、 启动(发送方);
}
私有bool setResult(对象对象对象,字符串文本)
{ 
if(this.textBox1.invokererequired)
{
Func d=新Func(setResult);
返回(bool)this.Invoke(d,obj,text);
}
其他的
{
按钮btn=obj as按钮;
如果(btn!=null)
{
btn.Text=文本;
if((string)btn.Tag!=“start”)返回false;
}
返回true;
}
}
私有void Jogger2(对象mybtn)
{
int ii=0;
while(true)
{
睡眠(1000);
//替换为您的代码
ii+=1;
如果(!setResult(mybtn,ii.ToString())中断;
}
}

假设您在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;
}

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

试试这个。在重新构建或运行之后,您应该在工具箱的顶部有一个新的“ButtonTimer”。在你的表单上放几个,运行它,看看当你点击它们时会发生什么。右键单击它们以“重置”它们:


我不明白Application.DoEvents()应该如何发挥作用?@JohnIvey在你的循环中我把它放在while(true)语句中,仍然是“挂起”的:\用时间代替睡眠。等等,我会用线程和应用程序来发布解决方案,我知道你在说什么。我的另一个问题是我有(16)个按钮。每个都有不同的名字。每个人都必须有一个不同的时间,彼此分开\我不太明白你想做什么。你有(或想要)一个或多个计时器吗?当点击某个按钮或某个特定按钮时,您想启动/停止秒表吗?您正在休眠主线程,导致UI冻结。我有多个按钮,每个按钮控制自己的计时器。它们各自定时器的启动和停止由按钮本身控制。因此,当button1打开时,计时器启动并在button1.Text上显示。停止按钮1关闭。它必须能够在任何其他的时间同时做到这一点。所以按钮1和按钮5可以打开并运行它们自己的定时器。明白吗?你的“按钮”应该是从按钮派生出来的,或者是一个用户控件,这样所有的功能都可以封装在它自己里面。这将允许它们彼此独立运行,而不依赖于表单代码进行操作。另外,您应该使用Stopwatch类和一个简单的Timer()将appeased()属性更新为按钮的文本。@JohnIvey检查我的帖子。也测试过了。我想这是你想要的。你可以附加任意多个按钮。我真的希望时间字符串出现在按钮中。(即按钮1.Text)还是我只是误解了你的代码?
class CheckboxCounter
{
    public CheckBox CheckBox;

    public int Time;
}
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();
    }

}