很奇怪 注释掉textbox相关的代码 Lable 就能显示, 如果一起显示的话只能显示textbox上的时间,Lable 什么都不显示了
源程序如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Timers;namespace colock
{
public partial class Form1 : Form
{
private Clock clock;
private Clock clock1;
public Form1()
{
InitializeComponent();
clock = new Clock(digital);
clock1 = new Clock(label2);
}
private void start_Click(object sender, System.EventArgs e)
{
this.clock.Start();
this.clock1.Start();
}
private void stop_Click(object sender, System.EventArgs e)
{
this.clock.Stop();
this.clock1.Stop();
}
}
//调用委托显示当前时间类
class Ticker
{
//定义 Tick委托
public delegate void Tick(int hh, int mm, int ss); //定义 Tick委托的事件tick
public event Tick tick; //实例化Timer类的ticking 对象
private System.Timers.Timer ticking = new System.Timers.Timer(); //定义了Ticker类的构造函数,实现每秒钟调用一次OnTimedEvent()方法引发一次事件通知
public Ticker()
{
this.ticking.Elapsed += new ElapsedEventHandler(this.OnTimedEvent);
this.ticking.Interval = 1000; // 1 second
this.ticking.Enabled = true;
}
private void Notify(int hours, int minutes, int seconds)
{
if (this.tick != null)
{
this.tick(hours, minutes, seconds);
}
}
//引发事件通知
private void OnTimedEvent(object source, ElapsedEventArgs args)
{
int hh = args.SignalTime.Hour;
int mm = args.SignalTime.Minute;
int ss = args.SignalTime.Second;
Notify(hh, mm, ss);
}
}
//格式化时钟的显示格式类
class Clock
{
private TextBox display;
private Label displayLabel;
private Ticker pulsed = new Ticker();
public Clock(TextBox displayBox)
{
this.display = displayBox;
}
public Clock(Label displayLabelText)
{
this.displayLabel = displayLabelText;
}
//将方法连接到事件
public void Start()
{
pulsed.tick += this.RefreshTime;
}
//将方法从事件断开
public void Stop()
{
pulsed.tick -= this.RefreshTime;
}
//格式化时间输出
private void RefreshTime(int hh, int mm, int ss)
{
this.display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss);
this.displayLabel.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss);
} }
//程序入口类
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}
源程序如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Timers;namespace colock
{
public partial class Form1 : Form
{
private Clock clock;
private Clock clock1;
public Form1()
{
InitializeComponent();
clock = new Clock(digital);
clock1 = new Clock(label2);
}
private void start_Click(object sender, System.EventArgs e)
{
this.clock.Start();
this.clock1.Start();
}
private void stop_Click(object sender, System.EventArgs e)
{
this.clock.Stop();
this.clock1.Stop();
}
}
//调用委托显示当前时间类
class Ticker
{
//定义 Tick委托
public delegate void Tick(int hh, int mm, int ss); //定义 Tick委托的事件tick
public event Tick tick; //实例化Timer类的ticking 对象
private System.Timers.Timer ticking = new System.Timers.Timer(); //定义了Ticker类的构造函数,实现每秒钟调用一次OnTimedEvent()方法引发一次事件通知
public Ticker()
{
this.ticking.Elapsed += new ElapsedEventHandler(this.OnTimedEvent);
this.ticking.Interval = 1000; // 1 second
this.ticking.Enabled = true;
}
private void Notify(int hours, int minutes, int seconds)
{
if (this.tick != null)
{
this.tick(hours, minutes, seconds);
}
}
//引发事件通知
private void OnTimedEvent(object source, ElapsedEventArgs args)
{
int hh = args.SignalTime.Hour;
int mm = args.SignalTime.Minute;
int ss = args.SignalTime.Second;
Notify(hh, mm, ss);
}
}
//格式化时钟的显示格式类
class Clock
{
private TextBox display;
private Label displayLabel;
private Ticker pulsed = new Ticker();
public Clock(TextBox displayBox)
{
this.display = displayBox;
}
public Clock(Label displayLabelText)
{
this.displayLabel = displayLabelText;
}
//将方法连接到事件
public void Start()
{
pulsed.tick += this.RefreshTime;
}
//将方法从事件断开
public void Stop()
{
pulsed.tick -= this.RefreshTime;
}
//格式化时间输出
private void RefreshTime(int hh, int mm, int ss)
{
this.display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss);
this.displayLabel.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss);
} }
//程序入口类
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}
用户代码未处理 System.NullReferenceException
Message="未将对象引用设置到对象的实例。"
Source="colock"
StackTrace:
在 colock.Clock.RefreshTime(Int32 hh, Int32 mm, Int32 ss) 位置 D:\tmp\colock\colock\Form1.cs:行号 105
在 colock.Ticker.Notify(Int32 hours, Int32 minutes, Int32 seconds) 位置 D:\tmp\colock\colock\Form1.cs:行号 62
在 colock.Ticker.OnTimedEvent(Object source, ElapsedEventArgs args) 位置 D:\tmp\colock\colock\Form1.cs:行号 72
在 System.Timers.Timer.MyTimerCallback(Object state)
InnerException: 可是我看不出问题来,请指导
private Label displayLabel = new Label();
问题解决了,可是手动执行又提示
用户代码未处理 System.InvalidOperationException
Message="线程间操作无效: 从不是创建控件“digital”的线程访问它。"
Source="System.Windows.Forms"
StackTrace:
在 System.Windows.Forms.Control.get_Handle()
在 System.Windows.Forms.Control.set_WindowText(String value)
在 System.Windows.Forms.TextBoxBase.set_WindowText(String value)
在 System.Windows.Forms.Control.set_Text(String value)
在 System.Windows.Forms.TextBoxBase.set_Text(String value)
在 System.Windows.Forms.TextBox.set_Text(String value)
在 colock.Clock.RefreshTime(Int32 hh, Int32 mm, Int32 ss) 位置 D:\tmp\colock\colock\Form1.cs:行号 105
在 colock.Ticker.Notify(Int32 hours, Int32 minutes, Int32 seconds) 位置 D:\tmp\colock\colock\Form1.cs:行号 62
在 colock.Ticker.OnTimedEvent(Object source, ElapsedEventArgs args) 位置 D:\tmp\colock\colock\Form1.cs:行号 72
在 System.Timers.Timer.MyTimerCallback(Object state)
InnerException:
这是什么原因呢,如果直接ctrl+F5就没有什么错误提示
怎么处理呢?google了半天还是不知道怎么修改! 希望高手指导一下!!!!
this.displayLabel.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss);
this.displayLabel.Refresh();
private Label displayLabel = new Label(); 修改成这样问题就解决了, 但是如果只显示一个用private TextBox display;也行呢? 没有搞明白,谁说说?另外修改后 按f5 会出现这个错误提示,如果是ctr+f5 就没有问题,执行正常
Message="线程间操作无效: 从不是创建控件“digital”的线程访问它。"
怎么处理呢?google了半天还是不知道怎么修改! 希望高手指导一下!!!!
private Label displayLabel = new Label();
开始的时候没有实例化,clock = new Clock(display);进行构造的时候displayLabel 为null,clock1 = new Clock(displayLabel); 进行构造的时候,display 为null,最终导致System.NullReferenceException.
{
this.display = displayBox;
}
public Clock(Label displayLabelText)
{
this.displayLabel = displayLabelText;
} this.display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss);
this.displayLabel.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss); 因为这两个控件你是从线程外部引用的,所以不能直接给text赋值,而是要用委托delegate void SetText(String Text);this.display.Invoke(new SetText(DoSetText),new Object[]{string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss)});void DoSetText(String Text)
{
this.display=Text;
}
is...thr...call = false;前面的单词忘了,用Ctrl+J 看看,可以防止报“进程间不能调用”的问题不过最好用异步的方式折腾
delegate void SetText(String Text); this.display.Invoke(new SetText(DoSetText),new Object[]{string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss)}); void DoSetText(String Text)
{
this.display=Text;
}
语法错误?!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace Clock
{
public partial class Form1 : Form
{
Clock clock;
Clock clock1; public Form1()
{
InitializeComponent();
clock = new Clock(digital);
clock1 = new Clock(label2); clock.Tick +=new Clock.TimeTick(clock_Tick);
} void clock_Tick(int Hour, int Minute, int Second)
{
this.Text = Hour.ToString() + ":" + Minute.ToString() + ":" + Second.ToString();
} void start_Click(object sender, System.EventArgs e)
{
this.clock.Start();
this.clock1.Start();
} void stop_Click(object sender, System.EventArgs e)
{
this.clock.Stop();
this.clock1.Stop();
}
} class Clock
{
Control Display;
Thread T = null;
bool Done = false;
public delegate void TimeTick(int Hour, int Minute, int Second);
public event TimeTick Tick;
delegate void SetText(String Text); public Clock(Control Display)
{
this.Display = Display;
} public void Start()
{
Done = false;
T = new Thread(new ThreadStart(ShowTime));
T.Start();
} public void Stop()
{
Done = true;
} void ShowTime()
{
int Start = Environment.TickCount;
int Begin = Start; while (!Done)
{
int End = Environment.TickCount;
if (End - Start > 1000)
{
DateTime DT = new DateTime((End - Begin) * 10000);
// 因为 Display和它的父窗口在同一个线程里,所以可以代替它的父窗口进行Invoke
Display.Invoke(new SetText(DoSetText), DT.ToString("HH:mm:ss"));
if (Tick != null)
this.Display.Invoke(new TimeTick(Tick), new Object[] { DT.Hour, DT.Minute, DT.Second });
Start = End;
}
}
} void DoSetText(String Text)
{
Display.Text = Text;
}
}
}不要用timer,否则一个timer里的Tick事件的处理时间长度会影响到其他的timer
// 因为 Display和它的父窗口在同一个线程里,所以可以代替它的父窗口进行Invoke
是针对
this.Display.Invoke(new TimeTick(Tick), new Object[] { DT.Hour, DT.Minute, DT.Second });