private void button1_Click(object sender, EventArgs e)
{
//////////////собираем новые данные
string carnam, carnum, driv, inf1;
carnam = textBox1.Text;
carnum = textBox2.Text;
driv = comboBox1.Text;
inf1 = textBox3.Text ;
///////////передаем на главную форму в datagridview1
Form1 form1 = this.Owner as Form1; ////////организация связи между формами
form1.dataGridView1.Rows[IndexForm].Cells[2].Value = carnam;
form1.dataGridView1.Rows[IndexForm].Cells[3].Value = carnum;
form1.dataGridView1.Rows[IndexForm].Cells[4].Value = driv;
form1.dataGridView1.Rows[IndexForm].Cells[5].Value = inf1;
////////////и сохраняем в БД
form1.carSave(); /////////моя попытка сохранения данных с грида в БД
Hide();
}
C#. Сохранение БД с DataGridView
Имеется главная форма. На ней DataGridView, в который выводится база sql. Кликом по любой записи в DataGridView открывается вторая форма, в которой редактируются данные с DataGridView .По нажатии кнопки ок на этой (второй) форме, она прячется, сохраняя новые данные в DataGridView. Но не могу допереть, как сделать, чтобы данные сохранялись сразу же и в БД тоже.
Вот код кнопки сохранения на второй форме (form2):
Код:
функция carSave() в коде главной формы (form1):
Код:
public void carSave()
{
carcb = new SqlCommandBuilder(caradapter);
caradapter.UpdateCommand = carcb.GetUpdateCommand();
caradapter.Update(carDataSet.Tables[0]);
}
{
carcb = new SqlCommandBuilder(caradapter);
caradapter.UpdateCommand = carcb.GetUpdateCommand();
caradapter.Update(carDataSet.Tables[0]);
}
Причем функция carSave() работает, как надо, если ее запускать кнопкой с главной формы, т.е. все сохраняется в базу. Со второй формы этого же не проходит. Почему так? Подскажите чего-нибудь..
Код кнопки с формы 1 наверняка не содержит команд вида dataGridView1.Rows[IndexForm].Cells[2].Value = carnam; ?
Ведь по моей логике, всё верно: заполняем датагрид, и выполняем функцию сохранения. Это проходит, если на второй форме нажать кнопку сохранения, при этом данные в гриде изменятся, но не сохранятся в БД, а затем если на первой(главной) форме нажимаем кнопку (которой быть не должно) с функцией carSave(), все сохраняется в БД.
Полагаю, смена содержимого ячейки "руками" и смена содержимого ячейки кодом вида dataGridView1.Rows[IndexForm].Cells[2].Value = carnam; приводит к разным результатам. Или везде надо использовать DB-Aware controls или менять подлежащий таблице DataSet а не его представление
Так я руками нигде и не меняю. Меняю только кодом, просто сохраняется это в БД, только с главной формы. Я ж выше написал..
Код:
form1.carSave(); /////////моя попытка сохранения данных с грида в БД
А вообще я бы поставил вызов carSave() после выхода из формы. То есть после выполнения открытия формы2 (по клику в гриде) попробыйте вызвать carSave().
Я недавно писал нечто подобное и сделал следующим образом:
У меня (в форме1, в гриде) был список пользователей с полями типа ID, ФИО, логин и т.д. Для изменения, по даблклику строки, открывалась форма2. В ней была возможность изменить все поля, кроме ID записи в таблице. В форме2 я отслеживал изменение данных. При нажатии на ОК проверял, если изменения происходили, прям из этой формы отсылал запрос на update в базу, закрывал форму2 и обновлял грид в первой форме.
Так-же хочу заметить, все манипуляции с базой я держал в отдельном классе (судя по всему как и вы).
Отличие в наших подходах в том, что я обновлял не через первую форму, а прямо из второй. После закрытия второй делал запрос к базе (это конечно увеличивает трафик, но для моей задачи не существенно), тем самым проверяя то ли я изменил.
Если нужен код, пишите я скину.
Цитата:
А вообще я бы поставил вызов carSave() после выхода из формы. То есть после выполнения открытия формы2 (по клику в гриде) попробыйте вызвать carSave().
Не совсем понял..Мне ведь нужно чтоб по кнопке на второй форме сохраняло. При ее создании, данные то еще не отредактированны.
Цитата:
Если нужен код, пишите я скину.
Скиньте, если можно.
Цитата:
Не совсем понял..Мне ведь нужно чтоб по кнопке на второй форме сохраняло. При ее создании, данные то еще не отредактированы.
Вы писали:
Код:
///////////передаем на главную форму в datagridview1
Form1 form1 = this.Owner as Form1; ////////организация связи между формами
form1.dataGridView1.Rows[IndexForm].Cells[2].Value = carnam;
form1.dataGridView1.Rows[IndexForm].Cells[3].Value = carnum;
form1.dataGridView1.Rows[IndexForm].Cells[4].Value = driv;
form1.dataGridView1.Rows[IndexForm].Cells[5].Value = inf1;
Form1 form1 = this.Owner as Form1; ////////организация связи между формами
form1.dataGridView1.Rows[IndexForm].Cells[2].Value = carnam;
form1.dataGridView1.Rows[IndexForm].Cells[3].Value = carnum;
form1.dataGridView1.Rows[IndexForm].Cells[4].Value = driv;
form1.dataGridView1.Rows[IndexForm].Cells[5].Value = inf1;
Цитата:
По нажатии кнопки ок на этой (второй) форме, она прячется, сохраняя новые данные в DataGridView
Соответственно
у Вас есть код на форме1. Например
Код:
dataGridView1_Click(object sender, EventArgs e) // Или как он там у тя выглядит
{
//*****************
Form2.show();
if (Грид изменен) //незабываем проверять на изменение
{ carSave(); } //вызываем обновление базы
//********************
}
{
//*****************
Form2.show();
if (Грид изменен) //незабываем проверять на изменение
{ carSave(); } //вызываем обновление базы
//********************
}
Пройдите по шагам с заходом. Посмотрите что конкретно у вас происходит.
Код завтра скину. Щас нет доступа.
Цитата:
dataGridView1_Click(object sender, EventArgs e) // Или как он там у тя выглядит
{
//*****************
Form2.show();
if (Грид изменен) //незабываем проверять на изменение
{ carSave(); } //вызываем обновление базы
//********************
}
{
//*****************
Form2.show();
if (Грид изменен) //незабываем проверять на изменение
{ carSave(); } //вызываем обновление базы
//********************
}
Извиняюсь, может не понимаю, я в c# новичек. Но такой код не пройдет. Т.к. сохранение будет происходить только по клику на гридвьюв. Например если пользователь зайдет, изменит всего одну запись и выйдет с программы данные не сохранятся. Такое если только на таймер, но это не рационально.
С отладкой с заходом, оно все нормально переходит на нужную рабочую функцию. Что там конкретно посмотреть?
Отладка по рабочему и нерабочему варианту на шаге caradapter.Update(carDataSet.Tables[0]);. Что тут посмотреть? Вроде все идентично..
Код:
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
//Начинаю собирать данные с Формы1
string id = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
string login = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
string s_name = dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString();
string f_name = dataGridView1.Rows[e.RowIndex].Cells[3].Value.ToString();
string l_name = dataGridView1.Rows[e.RowIndex].Cells[4].Value.ToString();
bool status = (bool)dataGridView1.Rows[e.RowIndex].Cells[5].Value;
//Закончил собирать данные с Формы1
Change_User Form = new Change_User(id, login, s_name, f_name, l_name, status); // Создаю экземпляр Формы2 и передаю в нее данные с Формы1
Form.ShowDialog(); // Показываю форму2
DB_Connect(); // когда мы выйдем из Формы2, обновляем форму 1
}
{
//Начинаю собирать данные с Формы1
string id = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
string login = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
string s_name = dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString();
string f_name = dataGridView1.Rows[e.RowIndex].Cells[3].Value.ToString();
string l_name = dataGridView1.Rows[e.RowIndex].Cells[4].Value.ToString();
bool status = (bool)dataGridView1.Rows[e.RowIndex].Cells[5].Value;
//Закончил собирать данные с Формы1
Change_User Form = new Change_User(id, login, s_name, f_name, l_name, status); // Создаю экземпляр Формы2 и передаю в нее данные с Формы1
Form.ShowDialog(); // Показываю форму2
DB_Connect(); // когда мы выйдем из Формы2, обновляем форму 1
}
Во второй форме:
Код:
public partial class Change_User : Form
{
bool flagChang; // Флаг изменения
string id;
string login;
string s_name;
string f_name;
string l_name;
bool status;
public Change_User(string id, string login, string s_name, string f_name, string l_name, bool status) //Принимаю данные из первой формы. Затем приравниваю местные к полученным
{
InitializeComponent();
this.id = id;
this.login = login;
this.s_name = s_name;
this.f_name = f_name;
this.l_name = l_name;
this.status = status;
}
private void Change_User_Load(object sender, EventArgs e) // Вношу данные в нужные мне поля
{
label1.Text = id;
textBox1.Text = login;
textBox2.Text = s_name;
textBox3.Text = f_name;
textBox4.Text = l_name;
checkBox1.Checked = status;
flagChang = false;
button2.Text = "Закрыть";
button1.Visible = false;
}
private void button2_Click(object sender, EventArgs e) // Кнопка отмены
{
this.Close();
}
private void textBox1_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void textBox2_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void textBox3_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void textBox4_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void checkBox1_CheckedChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void Change_User_FormClosing(object sender, FormClosingEventArgs e) // Если нажали крестик у Формы2 и были изменения, то выводим сообщение
{
if (flagChang == true)
{
if (MessageBox.Show("В данной записи имеются несохраненные изменения.\t\nВы уверены, что хотите выйти не сохраняя их?", "Предупреждение", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) { }
else { e.Cancel = true; }
}
}
private void button1_Click(object sender, EventArgs e) // При нажатии на кнопку "Изменить"
{
// Собираем данные
this.login = textBox1.Text.ToString();
this.s_name = textBox2.Text.ToString();
this.f_name = textBox3.Text.ToString();
this.l_name = textBox4.Text.ToString();
this.status = checkBox1.Checked;
// Передаем их в класс для обновления базы
DB.DB_Connect(this.id, this.login, this.s_name, this.f_name, this.l_name, this.status, "UPDATE");
}
}
{
bool flagChang; // Флаг изменения
string id;
string login;
string s_name;
string f_name;
string l_name;
bool status;
public Change_User(string id, string login, string s_name, string f_name, string l_name, bool status) //Принимаю данные из первой формы. Затем приравниваю местные к полученным
{
InitializeComponent();
this.id = id;
this.login = login;
this.s_name = s_name;
this.f_name = f_name;
this.l_name = l_name;
this.status = status;
}
private void Change_User_Load(object sender, EventArgs e) // Вношу данные в нужные мне поля
{
label1.Text = id;
textBox1.Text = login;
textBox2.Text = s_name;
textBox3.Text = f_name;
textBox4.Text = l_name;
checkBox1.Checked = status;
flagChang = false;
button2.Text = "Закрыть";
button1.Visible = false;
}
private void button2_Click(object sender, EventArgs e) // Кнопка отмены
{
this.Close();
}
private void textBox1_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void textBox2_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void textBox3_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void textBox4_TextChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void checkBox1_CheckedChanged(object sender, EventArgs e) // Изменяю флаг при внесении изменений в поле
{
flagChang = true;
button2.Text = "Отмена";
button1.Visible = true;
}
private void Change_User_FormClosing(object sender, FormClosingEventArgs e) // Если нажали крестик у Формы2 и были изменения, то выводим сообщение
{
if (flagChang == true)
{
if (MessageBox.Show("В данной записи имеются несохраненные изменения.\t\nВы уверены, что хотите выйти не сохраняя их?", "Предупреждение", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) { }
else { e.Cancel = true; }
}
}
private void button1_Click(object sender, EventArgs e) // При нажатии на кнопку "Изменить"
{
// Собираем данные
this.login = textBox1.Text.ToString();
this.s_name = textBox2.Text.ToString();
this.f_name = textBox3.Text.ToString();
this.l_name = textBox4.Text.ToString();
this.status = checkBox1.Checked;
// Передаем их в класс для обновления базы
DB.DB_Connect(this.id, this.login, this.s_name, this.f_name, this.l_name, this.status, "UPDATE");
}
}
По поводу вашего прохода, Вы проверяли саму базу? В нее изменения вносятся? То-есть если зайти в саму БД там поменялись значения? По вашим скринам я не могу понять, что пришло, что ушло и что осталось. Если у вас в проге нет секретной инфы, выложите ее сюдя, я попробую пройтись по шагам и глянуть что не так. Правда результат не могу гарантировать ))), сам недавно увлекся c# -ом.
Значения не меняются в самой БД.
В общем у меня не получилось.
А Вам действительно нужен именно метод Update? Мне кажется, что мой способ здесь вполне подходит. То есть во вторую форму передавайте еще ID и оттуда вызывайте
Код:
UPDATE ... SET ... WHERE id=id.
И еще, зачем так странно передаете значения из первой формы во вторую? Можно же проще:
В форме1
Код:
private void dataGridView1_CellMouseDoubleClick_1(object sender, DataGridViewCellMouseEventArgs e)
{
int index = dataGridView1.CurrentRow.Index;
string carnam, carnum, driv, inf1;
carnam = dataGridView1.Rows[index].Cells[2].Value.ToString();
carnum = dataGridView1.Rows[index].Cells[3].Value.ToString();
driv = dataGridView1.Rows[index].Cells[4].Value.ToString();
inf1 = dataGridView1.Rows[index].Cells[5].Value.ToString();
Form2 form2 = new Form2(carnam, carnum, driv, inf1, index);
form2.Owner = this;
form2.Show();
{
int index = dataGridView1.CurrentRow.Index;
string carnam, carnum, driv, inf1;
carnam = dataGridView1.Rows[index].Cells[2].Value.ToString();
carnum = dataGridView1.Rows[index].Cells[3].Value.ToString();
driv = dataGridView1.Rows[index].Cells[4].Value.ToString();
inf1 = dataGridView1.Rows[index].Cells[5].Value.ToString();
Form2 form2 = new Form2(carnam, carnum, driv, inf1, index);
form2.Owner = this;
form2.Show();
в форме2
Код:
public partial class Form2: Form
{
string carnam;
string carnum;
string driv;
string inf1;
int index=0;
public Form2(string carnam, string carnum, string driv, string inf1, int index)
{
InitializeComponent();
this.carnam = carnam;
this.carnum = carnum;
this.driv = driv;
this.inf1 = inf1;
this.index = index;
}
private void Form2_Load(object sender, EventArgs e)
{
Form1 form1 = this.Owner as Form1;
textBox1.Text = this.carnam;
//И так далее
{
string carnam;
string carnum;
string driv;
string inf1;
int index=0;
public Form2(string carnam, string carnum, string driv, string inf1, int index)
{
InitializeComponent();
this.carnam = carnam;
this.carnum = carnum;
this.driv = driv;
this.inf1 = inf1;
this.index = index;
}
private void Form2_Load(object sender, EventArgs e)
{
Form1 form1 = this.Owner as Form1;
textBox1.Text = this.carnam;
//И так далее
Цитата:
И еще, зачем так странно передаете значения из первой формы во вторую? Можно же проще:
Да это я пробовал другой способ.
Спасибо, за помощь. Попробую вашим методом. Однако всеравно интересно, почему мой не работает.
Заметил особенность. Если изменить значение в datagridview в ручную, при отключенном ридонли, cохранение со второй формы происходит отлично. Уважаемый Phodopus, был прав. Буду благодарен если ответите мне, более подробно, как мне поступить в этой ситуации. Желательно с примерами, ибо новичек.
Может из-за того, что последняя редактируемая строчка, как бы находится в режиме редактирования в DataSet и соответвенно из-за этого не может сохранится?
Не знаю можно ли таким образом завершить изменение данных сразу в dataSet напрямую, но сделал через bindingsource
Код:
public void carSave()
{
carBS.DataSource = carDataSet.Tables[0];
carBS.EndEdit();
dataGridView1.DataSource = carBS;
carcb = new SqlCommandBuilder(caradapter);
caradapter.UpdateCommand = carcb.GetUpdateCommand();
caradapter.Update(carDataSet.Tables[0]);
}
{
carBS.DataSource = carDataSet.Tables[0];
carBS.EndEdit();
dataGridView1.DataSource = carBS;
carcb = new SqlCommandBuilder(caradapter);
caradapter.UpdateCommand = carcb.GetUpdateCommand();
caradapter.Update(carDataSet.Tables[0]);
}