我有一个C#Windows窗体,有几个文本框和按钮。它还有一个显示sql表的数据网格视图。我创建了一个刷新按钮,允许我刷新表,以便我可以在表中看到更新的项目。我想知道有没有办法自己刷新表。就像每10秒钟一样。或者不是桌子,也许整个表格每10秒加载或刷新一次?
答案 0 :(得分:21)
使用Timer控件,调用UI线程并通过表单设计器为您提供控件。
private void Form1_Load(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = (10 * 1000); // 10 secs
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
//refresh here...
}
答案 1 :(得分:3)
您可以使用System.Windows.Forms.Timer
控制来刷新表单控件。
试试这个:
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
timer1.Interval=5000;//5 seconds
timer1.Tick += new System.EventHandler(timer1_Tick);
timer1.Start();
private void timer1_Tick(object sender, EventArgs e)
{
//do whatever you want
RefreshControls();
}
答案 2 :(得分:1)
这就是我经常处理它的方式。
场景:某些线程应该每隔n秒更新一次,但我们希望能够在该时间用完之前触发更新,而不会有任何阻塞任何内容。
private static readonly TimeSpan timeout = TimeSpan.FromSeconds(10);
private static readonly object Synchronizer = new { };
public static void idle()
{
//make sure, it is only called from the Thread that updates.
AssertThread.Name("MyUpdateThreadName");
lock (Synchronizer) {
Monitor.Wait(Synchronizer, timeout);
}
}
public static void nudge()
{
//anyone can call this
lock (Synchronizer) {
Monitor.PulseAll(Synchronizer);
}
}
这里,idle()将从执行更新的线程调用,并且可以从任何地方调用nudge()以在超时到期之前开始更新。
由于Wait和Pulse之间的复杂交互,考虑到同步器的锁定状态,即使很多微调速度非常快,它也非常可靠。 这也有从未死亡的巧妙副作用(b)锁定更新线程。
当然,如果更新涉及GUI内容,则必须进行整个InvokeRequired巡视。这意味着在更新线程的while循环中它看起来像
if (MyForm.InvokeRequired)
MyForm.BeginInvoke(sendinfo, message);
else
sendinfo(message);
sendinfo可能是某种Action或Delegate。 而且你永远不会直接从GUI线程调用idle()!
到目前为止我能找到的唯一不那么明显的行为: 如果你有很多微调,并且Thread实际上正在更新GUI,那么Invoke()和BeginInvoke()之间存在巨大差异。根据您的需要,Invoke实际上为GUI提供了对交互做出反应的时间,而BeginInvoke可以快速填充消息泵并使GUI不受限制(在我的情况下(奇怪的是)想要的行为:-))。
答案 3 :(得分:-2)
我不确定这两个答案是否真的是个好主意。 如果GUI更新(上帝要小心,但它可能,想象一下后面的Windows Update :-))会花费超过1秒的时间。不会导致来自创建线程的消息泵堵塞吗?
我刚刚在这里找到答案: What if a timer can not finish all its works before the new cycle time arrives?
如果我们使用正确的Timer类,一切都很好,或者引用Jim Mischel先生:如果您正在使用System.Windows.Forms.Timer,那么新的tick将不会发生,直到前一个已完成处理。
我也会在刻度事件开始时停止计时器并在之后再次启动计时器,但这只是因为我不需要连续两次更新。
通常我会使用Monitor Wait / Pulse,但在这种情况下,非常舒服,定时器事件在gui线程中执行,所以不需要调用任何东西。
由于我还需要手动更新(即不是从刻度线),我的代码看起来像这样:
在InitializeComponent()
之后 //if you use the wrong one here, you will get in great trouble :-)
guiUpdateTimer = new System.Windows.Forms.Timer { Interval = 1000 };
guiUpdateTimer.Tick += (sender, args) => updateGUI();
guiUpdateTimer.Start();
和
private void updateGUI()
{
guiUpdateTimer.Stop();
unsafe_updateGUI(); //inhere we actually access the gui
guiUpdateTimer.Start();
}
如果将unsafe_updateGUI()调用包装在适当的InvokeRequired检查中,甚至可以从GUI线程外部调用它。
哦,是的,对于OP场景,这很可能不是最好的方式......