Установка DataGridView.FirstDisplayedScrollingRowIndex останавливает срабатывание таймера? - PullRequest
1 голос
/ 07 марта 2012

Хорошо, новая головоломка! Очень простая проверка концепции: 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 выполнение идет, как и ожидалось: в окне сообщения указано «True», а заголовок продолжает расти с новыми символами «|». Раскомментируйте строку 2 и ... без окна сообщения!?, Без обновления заголовка, но без исключений !? Это запускается непосредственно из VS2010 в режиме отладки, может ли отладчик проглотить какие-либо исключения (я никогда не видел этого)? Считайте, что, поскольку никакое окно сообщения не появляется, это указывает на , проблема в том, чтобы запустить таймер , => это не будет срабатывать Но, как я уже сказал, единственным изменением является раскомментирование строки 2. Как / почему это влияет на таймер!?

Хорошо, следующее, что нужно попробовать, - это избежать повторной компиляции, сделав динамическое переключение (например, с помощью флажка), сохранять ли положение прокрутки или нет, с оставшейся частью визуализации на месте, возможно, это подвергнет что-то явное ..

Ответы [ 2 ]

1 голос
/ 08 марта 2012

Edit2 : Ну, я наконец нашел основную причину: при включенной строке 2 oTimer.Start( ) не вызывается. И причина в том, что во время самого первого вызова LoadData () [из frmMain_Load (..)] строка 2 создает исключение (, потому что начальное значение этого индекса равно -1, и это недопустимое значение, которое должно быть назначено назад )! Правильный способ сохранить положение прокрутки - изменить строку 2 следующим образом:

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

Однако неприятно то, что без добавления явного блока try-catch в LoadData () я бы его не нашел! Похоже, во время инициализации / загрузки формы все исключения незаметно проглатываются !! Извлеченный урок; но IMHO, это не очень хороший подход, принятый Microsoft, так как я даже не могу теперь полагаться на отладчик VS, чтобы объявить разумно высокоуровневые исключения, которые могут произойти в потоке пользовательского интерфейса в WinForm.

Ответный представитель идет к @appclay, я бы отдал его Дэвиду Холлу, поскольку он первым намекнул на такую ​​возможность.
Спасибо всем ребята!

1 голос
/ 07 марта 2012

Вероятно, это должен быть комментарий, но у меня недостаточно очков репутации, чтобы комментировать, так что ...

Вы поставили точку останова на oTimer.Start ()? Завершается ли первый вызов LoadData () в frmMain_Load ()? Ваше соединение открыто? Возможно, есть исключение, которое так или иначе проглатывается, как упоминал Дэвид Холл ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...