C# TabPage冻结应用程序
我有一个TabControl,有几个TabPages。我想做的是改变标签,让它在不同的标签上调用richtextbox。我会试着在代码之后更好地表达这个问题C# TabPage冻结应用程序,c#,tabcontrol,tabpage,C#,Tabcontrol,Tabpage,我有一个TabControl,有几个TabPages。我想做的是改变标签,让它在不同的标签上调用richtextbox。我会试着在代码之后更好地表达这个问题 void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e) { switch(tabControl1.SelectedTab.Name) { case "tabPage_ProdOrd
void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(tabControl1.SelectedTab.Name)
{
case "tabPage_ProdOrders":
dostuff();
break;
}
//throw new System.NotImplementedException();
}
void dostuff()
{
while (tabControl1.SelectedTab == tabControl1.TabPages["tabPage_ProdOrders"])
{
safeCall("testing...\n");
Thread.Sleep(10000);
}
}
delegate void SetTextCall(string s);
public void safeCall(string s)
{
if (this.richTextBox1.InvokeRequired)
{
SetTextCall d = new SetTextCall(safeCall);
this.Invoke(d, new object[] { s });
}
else this.richTextBox1.AppendText(string.Format(":{0}:\n",s));
}
我知道它看起来很邋遢-对不起。所以richtextbox驻留在tabpage“tabpage_DEV”上。我试图做到的是,当我切换到tabpage“tabpage\u ProdOrders”时,让它将文本附加到“tabpage\u DEV”上的richtextbox中。此外,这是一个确保一切顺利运行的测试,我最终要做的是,一旦选择了“tabPage_ProdOrders”,我将有一个gridview绑定到我的数据库,只要选择了该页面,它将每隔X秒从数据库刷新一次。问题是,只要我选择“tabPage_ProdOrders”,整个应用程序就会冻结。我假设这是由于while循环中的线程.Sleep()(我的假设是,由于该空是窗口的一部分,因此当它是.Sleep()时,整个窗体是.Sleep()正确的?任何关于解决方法的指导都是非常好的。在窗体中添加一个计时器,并对其Tick事件进行编码,以完成所有DB工作 更改dostuff方法,如下所示:
void dostuff()
{
if (tabControl1.SelectedTab == tabControl1.TabPages["tabPage_ProdOrders"])
{
dbTimer.Interval = 10000; // your interval in ms
dbTimer.Start();
}
else dbTimer.Stop();
}
使用Thread.Sleep(..)您发送当前的,即要睡眠的GUI线程。这不是您想要的。我使用了与TaW的建议类似的方法
delegate void populateProdOrders(DataTable dt);
public void safePopulate(DataTable dt)
{
if (this.dataGridView2.InvokeRequired)
{
populateProdOrders d = new populateProdOrders(safePopulate);
this.Invoke(d, new object[] { dt });
}
else this.dataGridView2.DataSource = dt;
}
public Form1()
{
// stuff
System.Timers.Timer refreshProdOrders = new System.Timers.Timer(5000);
refreshProdOrders.Elapsed += refreshProdOrders_Elapsed;
refreshProdOrders.AutoReset = true;
refreshProdOrders.Enabled = true;
}
void refreshProdOrders_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//dostuff();
var globes = SharedResourceVariables.globals;
DataTable dt = new DataTable();
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(globes.SQLConn);
using (conn)
{
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("development_usp_viewProdductionOrders", conn);
cmd.CommandType = CommandType.StoredProcedure;
using (cmd)
{
conn.Open();
System.Data.SqlClient.SqlDataReader dr = cmd.ExecuteReader();
dt.Load(dr);
conn.Close();
}
}
safePopulate(dt);
}
您希望如何离开
while
循环?sob-dur…好的,我应该使while循环调用确定while循环的状态…类似while(method()){…sleep()};然后在method()中类似return(tabControl1.SelectedTab==tabControl1.TabPages[“tabPage\u ProdOrders”])?真:假;…但我仍然觉得这会挂在。睡眠正确吗?选项卡将如何更改?通过用户交互?在这种情况下,请不要在循环中等待它!!你为什么要调用睡眠?只是想知道:可能是你根本不懂GUI编程吗?你对用户做出反应,GUI完成所有等待..bec因为它需要在一个定时循环中从数据库刷新-有作业一直在数据库上运行更改数据。我的源绑定到该数据库。我需要在X个时间段后刷新,以避免数据库和连接过载。如果用户在该页面停留“永远”无论用户的交互如何,它都需要继续更新。选项卡控件是通过用户交互更改的。我希望避免线程旋转并执行此操作,然后在数据更改时触发事件,以更新网格-但这可能是最好的方式吗?我只是觉得它应该*是更多的东西mplistic。是的,这就是我假设发生的事情-我知道我做了一些愚蠢/错误的事情,但没有看到它。谢谢你给我指出相应的计时器。我确实在表单上使用了计时器,因为无论用户是否在该选项卡页上,更新该选项卡页都会更好。再次感谢!(FWIW,不,我通常不会编写GUI的代码)