C# c语言中的秒表更改按钮文本#
基本上,我的表单中有多个按钮,我想在按钮中显示秒表。按下按钮时显示文本。(按钮修改为切换按钮。)以及在按钮关闭时停止并重置定时器。看起来很简单,但因为我有多个按钮,可以按任何顺序按下,而且我对线程一无所知,所以这似乎比我想象的要困难得多 我最初的目的是要有一个功能,该功能每秒钟持续运行一次,并且仅当按下按钮时,才使用以下代码对interager进行交互: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
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 IveyApplication.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();
}
}