Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

C#. Сохранение БД с DataGridView

75K
01 декабря 2011 года
Loncaster
11 / / 01.12.2011
Всем доброго времени суток.
Имеется главная форма. На ней DataGridView, в который выводится база sql. Кликом по любой записи в DataGridView открывается вторая форма, в которой редактируются данные с DataGridView .По нажатии кнопки ок на этой (второй) форме, она прячется, сохраняя новые данные в DataGridView. Но не могу допереть, как сделать, чтобы данные сохранялись сразу же и в БД тоже.
Вот код кнопки сохранения на второй форме (form2):
Код:
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();
        }


функция carSave() в коде главной формы (form1):
 
Код:
public void carSave()
        {
            carcb = new SqlCommandBuilder(caradapter);
            caradapter.UpdateCommand = carcb.GetUpdateCommand();
            caradapter.Update(carDataSet.Tables[0]);
        }


Причем функция carSave() работает, как надо, если ее запускать кнопкой с главной формы, т.е. все сохраняется в базу. Со второй формы этого же не проходит. Почему так? Подскажите чего-нибудь..
14
01 декабря 2011 года
Phodopus
3.3K / / 19.06.2008
Код кнопки с формы 1 наверняка не содержит команд вида dataGridView1.Rows[IndexForm].Cells[2].Value = carnam; ?
75K
02 декабря 2011 года
Loncaster
11 / / 01.12.2011
Да, не содержит. А это оно мешает разве? Тогда как сделать в этом случае правельнее?
Ведь по моей логике, всё верно: заполняем датагрид, и выполняем функцию сохранения. Это проходит, если на второй форме нажать кнопку сохранения, при этом данные в гриде изменятся, но не сохранятся в БД, а затем если на первой(главной) форме нажимаем кнопку (которой быть не должно) с функцией carSave(), все сохраняется в БД.
14
03 декабря 2011 года
Phodopus
3.3K / / 19.06.2008
Полагаю, смена содержимого ячейки "руками" и смена содержимого ячейки кодом вида dataGridView1.Rows[IndexForm].Cells[2].Value = carnam; приводит к разным результатам. Или везде надо использовать DB-Aware controls или менять подлежащий таблице DataSet а не его представление
75K
03 декабря 2011 года
Loncaster
11 / / 01.12.2011
Так я руками нигде и не меняю. Меняю только кодом, просто сохраняется это в БД, только с главной формы. Я ж выше написал..
18K
04 декабря 2011 года
imAlex
179 / / 29.07.2010
Попробуйте в режиме отладчика посмотреть что у вас происходит в
 
Код:
form1.carSave();     /////////моя попытка сохранения данных с грида  в БД

А вообще я бы поставил вызов carSave() после выхода из формы. То есть после выполнения открытия формы2 (по клику в гриде) попробыйте вызвать carSave().
Я недавно писал нечто подобное и сделал следующим образом:
У меня (в форме1, в гриде) был список пользователей с полями типа ID, ФИО, логин и т.д. Для изменения, по даблклику строки, открывалась форма2. В ней была возможность изменить все поля, кроме ID записи в таблице. В форме2 я отслеживал изменение данных. При нажатии на ОК проверял, если изменения происходили, прям из этой формы отсылал запрос на update в базу, закрывал форму2 и обновлял грид в первой форме.
Так-же хочу заметить, все манипуляции с базой я держал в отдельном классе (судя по всему как и вы).
Отличие в наших подходах в том, что я обновлял не через первую форму, а прямо из второй. После закрытия второй делал запрос к базе (это конечно увеличивает трафик, но для моей задачи не существенно), тем самым проверяя то ли я изменил.
Если нужен код, пишите я скину.
75K
04 декабря 2011 года
Loncaster
11 / / 01.12.2011
Цитата:
А вообще я бы поставил вызов carSave() после выхода из формы. То есть после выполнения открытия формы2 (по клику в гриде) попробыйте вызвать carSave().


Не совсем понял..Мне ведь нужно чтоб по кнопке на второй форме сохраняло. При ее создании, данные то еще не отредактированны.

Цитата:
Если нужен код, пишите я скину.


Скиньте, если можно.

18K
04 декабря 2011 года
imAlex
179 / / 29.07.2010
Цитата:
Не совсем понял..Мне ведь нужно чтоб по кнопке на второй форме сохраняло. При ее создании, данные то еще не отредактированы.


Вы писали:

 
Код:
///////////передаем на главную форму в 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;

Цитата:
По нажатии кнопки ок на этой (второй) форме, она прячется, сохраняя новые данные в DataGridView


Соответственно
у Вас есть код на форме1. Например

 
Код:
dataGridView1_Click(object sender, EventArgs e) // Или как он там у тя выглядит
{
 //*****************
Form2.show();
if (Грид изменен) //незабываем проверять на изменение
{ carSave(); } //вызываем обновление базы
//********************
}

Пройдите по шагам с заходом. Посмотрите что конкретно у вас происходит.
Код завтра скину. Щас нет доступа.
75K
05 декабря 2011 года
Loncaster
11 / / 01.12.2011
Цитата:
dataGridView1_Click(object sender, EventArgs e) // Или как он там у тя выглядит
{
//*****************
Form2.show();
if (Грид изменен) //незабываем проверять на изменение
{ carSave(); } //вызываем обновление базы
//********************
}


Извиняюсь, может не понимаю, я в c# новичек. Но такой код не пройдет. Т.к. сохранение будет происходить только по клику на гридвьюв. Например если пользователь зайдет, изменит всего одну запись и выйдет с программы данные не сохранятся. Такое если только на таймер, но это не рационально.
С отладкой с заходом, оно все нормально переходит на нужную рабочую функцию. Что там конкретно посмотреть?

75K
05 декабря 2011 года
Loncaster
11 / / 01.12.2011
Отладка по рабочему и нерабочему варианту на шаге caradapter.Update(carDataSet.Tables[0]);. Что тут посмотреть? Вроде все идентично..

18K
05 декабря 2011 года
imAlex
179 / / 29.07.2010
Вот как я обрабатываю вызов второй формы из первой:
Код:
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          
        }

Во второй форме:
Код:
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");
        }
    }

По поводу вашего прохода, Вы проверяли саму базу? В нее изменения вносятся? То-есть если зайти в саму БД там поменялись значения? По вашим скринам я не могу понять, что пришло, что ушло и что осталось. Если у вас в проге нет секретной инфы, выложите ее сюдя, я попробую пройтись по шагам и глянуть что не так. Правда результат не могу гарантировать ))), сам недавно увлекся c# -ом.
75K
05 декабря 2011 года
Loncaster
11 / / 01.12.2011
Значения не меняются в самой БД.
Посмотрите
18K
05 декабря 2011 года
imAlex
179 / / 29.07.2010
Я попробовал. У меня не хочет работать GetUpdateCommand. Вашу базу я не смог прикрутить (у меня sql 2005), создал свою. Вроде и примери кей прикрутил, и в запросе его получаю, но все равно ругается на "... не возвращающей никаких сведений о столбце ключей."
В общем у меня не получилось.
А Вам действительно нужен именно метод 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();

в форме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;
           //И так далее
75K
05 декабря 2011 года
Loncaster
11 / / 01.12.2011
Цитата:
И еще, зачем так странно передаете значения из первой формы во вторую? Можно же проще:


Да это я пробовал другой способ.
Спасибо, за помощь. Попробую вашим методом. Однако всеравно интересно, почему мой не работает.

75K
06 декабря 2011 года
Loncaster
11 / / 01.12.2011
Всё же хочу заставить свой код работать.
Заметил особенность. Если изменить значение в datagridview в ручную, при отключенном ридонли, cохранение со второй формы происходит отлично. Уважаемый Phodopus, был прав. Буду благодарен если ответите мне, более подробно, как мне поступить в этой ситуации. Желательно с примерами, ибо новичек.
75K
06 декабря 2011 года
Loncaster
11 / / 01.12.2011
В общем так. Если редактировать подряд несколько значений, одно за другим, они все сохраняются в бд, кроме последнего редактируемого. Я уже весь мозг сломал..
Может из-за того, что последняя редактируемая строчка, как бы находится в режиме редактирования в DataSet и соответвенно из-за этого не может сохранится?
75K
06 декабря 2011 года
Loncaster
11 / / 01.12.2011
В общем я был прав. Решил проблему с помощью DataBindings.EndEdit();
Не знаю можно ли таким образом завершить изменение данных сразу в 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]);
        }
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог