设置DataGridView.FirstDisplayedScrollingRowIndex会停止计时器的触发吗?

时间:2012-03-06 22:44:50

标签: c# winforms .net-4.0 datagridview timer

好的,新的谜题!非常简单的概念验证设置:DataGridView,通过DataTable绑定到SQL视图。数据是动态的(尽管行数是常数),所以我添加了Forms.Timer来刷新它:

private DataTable   tbData= new DataTable( );

private void    frmMain_Load( object sender, EventArgs e )
{
    LoadData( );
    oTimer.Start( );
    MessageBox.Show( oTimer.Enabled.ToString( ) );
}
private void    frmMain_DoubleClick( object sender, EventArgs e )
{
    LoadData( );    // to reload on-demand - works perfectly
}
private void    LoadData( )
{
    SqlDataAdapter  da=
        new SqlDataAdapter( "select * from vwOne", Program.oSqlConn );

    tbData.Clear( );
    da.Fill( tbData );
    dgView.DataSource=  tbData;
}
private void    oTimer_Tick( object sender, EventArgs e )
{
    LoadData( );
    this.Text+= "|";
}

为了在刷新期间保持滚动位置,我添加了以下行(1和2):

private void    LoadData( )
{
    SqlDataAdapter  da=
        new SqlDataAdapter( "select * from vwOne", Program.oSqlConn );

    int iRow=   dgView.FirstDisplayedScrollingRowIndex; // 1-remember row

    tbData.Clear( );
    da.Fill( tbData );
    dgView.DataSource=  tbData;

    dgView.FirstDisplayedScrollingRowIndex=     iRow;   // 2-restore back
}

到目前为止一切顺利。现在这里是踢球者:没有第2行重新加载工作完美(不保留滚动),但是一旦我取消注释第2行计时器就停止了(oTimer_Tick中的断点永远不会被击中)!?

给出了什么!?

编辑:frmMain_DoubleClick(..)添加到上面的代码中(已经拥有它,并且一直在使用),它可以正常工作; 绝对没有抛出异常,也没有SQL连接问题。从字面上看,取消注释该行(#2)会产生完全不同,在oTimer_Tick中根本没有被调用!

根据建议(谢谢你们!)我添加了几行新内容:

  • frmMain_Load(..)显示oTimer.Enabled并确认它已完成到最后,
  • 并附加“|”每当oTimer_Tick(..)触发时形成标题。

如果没有第2行执行按预期执行:message-box显示'True'并且title继续增加新的'|'。取消注释第2行和..没有消息框!?,没有标题更新,但没有任何例外!?这是在调试模式下直接从VS2010运行,调试器是否可以吞下任何异常(我从未见过这个)?记住,因为没有显示消息框,这表明问题在于启动计时器,=>它不会开火。但就像我说的那样,唯一的变化就是取消注释第2行。如何/为什么会影响计时器??

好的,接下来要尝试的是通过动态切换(例如通过复选框)避免重新编译是否保留滚动位置,其余的可视化就位,也许这会暴露smth ..

2 个答案:

答案 0 :(得分:1)

这应该是一个评论,但我没有足够的声誉点来发表评论......

你有没有在oTimer.Start()上设置断点?第一次调用frmMain_Load()中的LoadData()是否完整?你的连接是否开放?正如大卫霍尔所提到的那样,也许有一种例外被吞没了......

答案 1 :(得分:1)

Edit2 :好吧,我终于找到了根本原因:启用第2行oTimer.Start( )没有被调用。原因是在第一次调用LoadData()[来自frmMain_Load(..)]时,第2行产生异常(,因为该索引的初始值为-1,这是要分配的无效值回的)!保持滚动位置的正确方法是改变第2行:

if(  iRow >= 0  )   dgView.FirstDisplayedScrollingRowIndex=     iRow;

然而令人讨厌的是,如果没有向LoadData()添加一个显式的try-catch块,我就找不到了!在表单初始化/加载期间看起来像正在静默吞下任何异常!! 经验教训;但恕我直言,这不是微软采取的一种好方法,因为我现在甚至不能依赖VS调试器来宣布可能在WinForm中的UI线程上发生的合理的高级异常。

回答代表@appclay,我会把它交给@David Hall,因为他是第一个暗示这种可能性的人。
谢谢大家!