Почему мой DataGridview отказывается обновлять?
Я обновляю строку в таблице. Подмножество таблицы отображается в DataGridView. Когда я обновляю строку, изменение не отражается в DataGridView. Несмотря на то, что после совершения изменения я вызываю DataGridView.Invalidate() и DataGridView.Refresh(), мне необходимо закрыть приложение, перезапустить и повторно запустить запрос, прежде чем можно будет увидеть изменение.
Соответствующий код:
private void buttonUpdate_Click(object sender, EventArgs e)
{
const int TICKETID_COLUMN = 0;
String _ticketID = dataGridView1.CurrentRow.Cells[SOME_COLUMN].Value.ToString();
UpdateRecord(_ticketID, textBoxTicketSource.Text,
textBoxAboutSomeID.Text, textBoxCategoryID.Text, textBoxContactEmail.Text);
}
private void UpdateRecord(string ATicketID, string ATicketSource, string
AAboutSomeID, string ACategoryID, string AContactID)
{
oracleConnection1.Open();
OracleCommand ocmd = new OracleCommand();
OracleTransaction ot;
// Start a local transaction
ot = oracleConnection1.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
// Assign transaction object for a pending local transaction
ocmd.Transaction = ot;
ocmd.Connection = oracleConnection1;
try
{
ocmd.CommandText = @"UPDATE ABC.CONCERTTICKETS
SET TICKETSOURCE = :p_TICKETSOURCE,
ABOUTSOMEID = :p_ABOUTSOMEID,
CATEGORYID = :p_CATEGORYID,
CONTACTEMAIL = :p_CONTACTEMAIL
WHERE TICKETID = :p_TICKETID";
ocmd.Parameters.Add("p_TICKETSOURCE", ATicketSource);
ocmd.Parameters.Add("p_ABOUTSOMEID", Convert.ToInt32(AAboutSOMEID));
ocmd.Parameters.Add("p_CATEGORYID", Convert.ToInt32(ACategoryID));
ocmd.Parameters.Add("p_CONTACTEMAIL", AContactID);
ocmd.Parameters.Add("p_TICKETID", ATicketID);
ocmd.ExecuteNonQuery();
ot.Commit();
Popul8TheGrid();
dataGridView1.Invalidate();
dataGridView1.Refresh();
}
catch (Exception e)
{
ot.Rollback();
throw;
}
finally
{
oracleConnection1.Close();
}
}
private void Popul8TheGrid()
{
int iFromYear = dateTimePickerFrom.Value.Year;
int iFromMonth = dateTimePickerFrom.Value.Month;
int iFromDay = dateTimePickerFrom.Value.Day;
int iToYear = dateTimePickerTo.Value.Year;
int iToMonth = dateTimePickerTo.Value.Month;
int iToDay = dateTimePickerTo.Value.Day;
oracleCommand1.Parameters.Clear();
oracleCommand1.Parameters.Add("iStartDate", new DateTime(iFromYear, iFromMonth,
iFromDay));
oracleCommand1.Parameters.Add("iEndDate", new DateTime(iToYear, iToMonth,
iToDay));
oracleCommand1.Parameters.Add("iCATEGORYID", 114);
// OracleRef is apparently like OracleDbType.RefCursor;
OracleRef or = new OracleRef("_or");
oracleCommand1.Parameters.Add("cref", or);
oracleConnection1.Open();
oracleDataAdapter1.SelectCommand = oracleCommand1;
oracleDataAdapter1.GetFillParameters();
oracleDataAdapter1.Fill(oracleDataTable1);
dataGridView1.DataSource = oracleDataTable1;
oracleConnection1.Close();
}
Обновлено:
Основываясь на предложении Холла (я попытался ответить комментарием, но он, похоже, завис):
Хорошо, у меня есть это сейчас:
oracleDataAdapter1.SelectCommand = oracleCommand1;
oracleDataAdapter1.GetFillParameters();
oracleDataAdapter1.Fill(oracleDataTable1);
// I don't see a "Clear" method or some such...
dataGridView1.DataSource = null;
//dataGridView1.DataSource = oracleDataTable1;
BindingSource b = new BindingSource();
b.DataSource = oracleDataTable1;
dataGridView1.DataSource = b;
b.ResetBindings(false);
oracleConnection1.Close();
... и все равно работает - обновляет, но DataGridView не знает об этом, пока я не перезапущу приложение.
3 ответа
Причина Invalidate()
а также Refresh()
не запрашивайте источник данных в том, что они предназначены для работы только с графической стороной - они делают недействительной клиентскую область элемента управления и вызывают перерисовку, но проблема в том, что базовый элемент управления считает, что ничего не изменилось в его источник данных, поскольку он полагается на источник данных, чтобы сообщить ему, когда это произойдет.
То, что вам нужно, это ваш DataSource
быть чем-то, что скажет DataGridView
что происходит, такие как BindingList<T>
или BindingSource
оба из которых имеют ListChanged
событие, которое DataGridView
подписывается на.
Я думал DataTable
также сообщил сетке, когда она изменилась, но я либо ошибся, либо OracleDataTable
это отличается.
Что должно решить проблему, так это введение BindingSource
и сделать это источником данных для DataGridView
, Тогда сделай свой OracleDataTable
источник данных источника привязки. Если это не работает, вы можете позвонить ResetBindings()
метод на источник привязки.
BindingSource b = new BindingSource();
b.DataSource = oracleDataTable1;
dataGridView1.DataSource = b;
Попробуйте сделать:
dataGridView1.DataSource = null;
dataGridView1.DataSource = oracleDataTable1;
dataGridView1.DataSource = null;
dataGridView1.DataBind();
dataGridView1.DataSource = oracleDataTable1;
dataGridView1.DataBind();