Перейти к содержимому

Datagrid как подключить бд

  • автор:

Практическое руководство. Привязка данных к элементу управления DataGridView в Windows Forms

Элемент управления DataGridView поддерживает стандартную модель привязки данных Windows Forms, допускающую привязку к разнообразным источникам данных. Обычно выполняется привязка к объекту BindingSource, который управляет взаимодействием с источником данных. Компонент BindingSource может быть любым источником данных Windows Forms, что обеспечивает большую гибкость при выборе или изменении расположения данных. Дополнительные сведения об источниках данных, поддерживаемых элементом управления DataGridView, см. в разделе Общие сведения об элементе управления DataGridView.

Visual Studio имеет обширную поддержку привязки данных к элементу управления DataGridView. Дополнительные сведения см. в статье Практическое руководство. Привязка данных к элементу управления DataGridView в Windows Forms с помощью конструктора.

Подключение элемента управления DataGridView к данным

  1. Реализуйте метод, обрабатывающий получение данных. В примере кода ниже реализован метод GetData , инициализирующий компонент SqlDataAdapter и использующий его для заполнения DataTable. Затем он привязывает DataTable к BindingSource.
  2. В обработчике событий Load формы привяжите элемент управления DataGridView к компоненту BindingSource и вызовите метод GetData для получения данных.

Пример

Этот полный пример кода извлекает данные из базы данных для заполнения элемента управления DataGridView в форме Windows. Форма также содержит кнопки для повторной загрузки данных и отправки изменений в базу данных.

Для этого примера требуются:

  • доступ к примеру базы данных Northwind. Дополнительные сведения об установке примера базы данных Northwind см. в разделе Получение примеров баз данных для примеров кода ADO.NET;
  • ссылки на сборки System, System.Windows.Forms, System.Data и System.Xml.

Чтобы выполнить сборку и запуск этого примера, вставьте код в файл кода Form1 в новом проекте Windows Forms. Сведения о сборке из командной строки C# или Visual Basic см. в разделах Сборка из командной строки с помощью csc.exe или Сборка из командной строки.

Заполните переменную connectionString в примере значениями для подключения к примеру базы данных Northwind на SQL Server. Проверка подлинности Windows, также называемая встроенной безопасностью, является более безопасным способом подключения к базе данных, чем хранение пароля в строке подключения. Дополнительные сведения о безопасности подключений см. в разделе Защита сведений о подключении.

using System; using System.Data; using System.Data.SqlClient; using System.Globalization; using System.Windows.Forms; namespace WindowsFormsApp < public partial class Form1 : Form < public Form1() < InitializeComponent(); >> > public class Form1 : Form < private DataGridView dataGridView1 = new DataGridView(); private BindingSource bindingSource1 = new BindingSource(); private SqlDataAdapter dataAdapter = new SqlDataAdapter(); private Button reloadButton = new Button(); private Button submitButton = new Button(); [STAThread()] public static void Main() < Application.Run(new Form1()); >// Initialize the form. public Form1() < dataGridView1.Dock = DockStyle.Fill; reloadButton.Text = "Reload"; submitButton.Text = "Submit"; reloadButton.Click += new EventHandler(ReloadButton_Click); submitButton.Click += new EventHandler(SubmitButton_Click); FlowLayoutPanel panel = new FlowLayoutPanel < Dock = DockStyle.Top, AutoSize = true >; panel.Controls.AddRange(new Control[] < reloadButton, submitButton >); Controls.AddRange(new Control[] < dataGridView1, panel >); Load += new EventHandler(Form1_Load); Text = "DataGridView data binding and updating demo"; > private void GetData(string selectCommand) < try < // Specify a connection string. // Replace with the SQL Server for your Northwind sample database. // Replace "Integrated Security=True" with user login information if necessary. String connectionString = "Data Source=;Initial Catalog=Northwind;" + "Integrated Security=True"; // Create a new data adapter based on the specified query. dataAdapter = new SqlDataAdapter(selectCommand, connectionString); // Create a command builder to generate SQL update, insert, and // delete commands based on selectCommand. SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter); // Populate a new data table and bind it to the BindingSource. DataTable table = new DataTable < Locale = CultureInfo.InvariantCulture >; dataAdapter.Fill(table); bindingSource1.DataSource = table; // Resize the DataGridView columns to fit the newly loaded content. dataGridView1.AutoResizeColumns( DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader); > catch (SqlException) < MessageBox.Show("To run this example, replace the value of the " + "connectionString variable with a connection string that is " + "valid for your system."); >> private void Form1_Load(object sender, EventArgs e) < // Bind the DataGridView to the BindingSource // and load the data from the database. dataGridView1.DataSource = bindingSource1; GetData("select * from Customers"); >private void ReloadButton_Click(object sender, EventArgs e) < // Reload the data from the database. GetData(dataAdapter.SelectCommand.CommandText); >private void SubmitButton_Click(object sender, EventArgs e) < // Update the database with changes. dataAdapter.Update((DataTable)bindingSource1.DataSource); >> 
Imports System.Data.SqlClient Imports System.Windows.Forms Public Class Form1 Inherits Form Private dataGridView1 As New DataGridView() Private bindingSource1 As New BindingSource() Private dataAdapter As New SqlDataAdapter() Private WithEvents ReloadButton As New Button() Private WithEvents SubmitButton As New Button() Public Shared Sub Main() Application.Run(New Form1()) End Sub ' Initialize the form. Public Sub New() dataGridView1.Dock = DockStyle.Fill ReloadButton.Text = "Reload" SubmitButton.Text = "Submit" Dim panel As New FlowLayoutPanel With < .Dock = DockStyle.Top, .AutoSize = True >panel.Controls.AddRange(New Control() ) Controls.AddRange(New Control() ) Text = "DataGridView data binding and updating demo" End Sub Private Sub GetData(ByVal selectCommand As String) Try ' Specify a connection string. ' Replace with the SQL Server for your Northwind sample database. ' Replace "Integrated Security=True" with user login information if necessary. Dim connectionString As String = "Data Source=;Initial Catalog=Northwind;" + "Integrated Security=True;" ' Create a new data adapter based on the specified query. dataAdapter = New SqlDataAdapter(selectCommand, connectionString) ' Create a command builder to generate SQL update, insert, and ' delete commands based on selectCommand. Dim commandBuilder As New SqlCommandBuilder(dataAdapter) ' Populate a new data table and bind it to the BindingSource. Dim table As New DataTable With < .Locale = Globalization.CultureInfo.InvariantCulture >dataAdapter.Fill(table) bindingSource1.DataSource = table ' Resize the DataGridView columns to fit the newly loaded content. dataGridView1.AutoResizeColumns( DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader) Catch ex As SqlException MessageBox.Show("To run this example, replace the value of the " + "connectionString variable with a connection string that is " + "valid for your system.") End Try End Sub Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.Load ' Bind the DataGridView to the BindingSource ' and load the data from the database. dataGridView1.DataSource = bindingSource1 GetData("select * from Customers") End Sub Private Sub ReloadButton_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles ReloadButton.Click ' Reload the data from the database. GetData(dataAdapter.SelectCommand.CommandText) End Sub Private Sub SubmitButton_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles SubmitButton.Click ' Update the database with changes. dataAdapter.Update(CType(bindingSource1.DataSource, DataTable)) End Sub End Class 

См. также

  • DataGridView
  • DataGridView.DataSource
  • BindingSource
  • Отображение данных в элементе управления DataGridView в Windows Forms
  • Защита сведений о подключении

Совместная работа с нами на GitHub

Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

Datagrid как подключить бд

Доброго времени суток!

есть форма. на ней есть кнопка и datagridview. Как вывести в datagridview результат: «select*from jour.bas» (БД jour, таблица bas).

Что было сделано:

 private void button3_Click(object sender, EventArgs e)

собственно говоря спрашиваю, т.к. сам разобраться не смог. Спасибо за помощь.

использую коннектор mysql/net.

Последний раз редактировалось sinj; 01.09.2011 в 22:07 .
программирователь
Пользователь
Регистрация: 15.02.2009
Сообщений: 72
подключение к бд происходит. datagridview пустой.
Последний раз редактировалось sinj; 01.09.2011 в 22:08 .
Регистрация: 25.08.2011
Сообщений: 2,841
Вот так необходимо сделать:

string CommandText = "select*from jour.bas"; string ConnectString = "Database=jour;Data Source=localhost;User myConnection = new MySqlConnection(ConnectString); MySqlCommand myCommand = new MySqlCommand(CommandText, myConnection); DataSet myDataSet= new DataSet() MySQLDataAdaptor = new MySQLDataAdaptor(); MySQLDataAdaptor.Connection = myConnection; MySQLDataAdaptor.Command = myCommand; myConnection.Open(); MySQLDataAdaptor.Fill(myDataSet); if (myDataSet.Tables.Count>0) DataGridView.DataSource = myDataSet.Tables[0];

Skype — wmaster_s E-Mail — WorldMasters@gmail.com
Работаем по 3 критериям — быстро, качественно, недорого. Заказчик выбирает любые два.

WorldMaster
Посмотреть профиль
Найти ещё сообщения от WorldMaster

программирователь
Пользователь
Регистрация: 15.02.2009
Сообщений: 72
Сделал иначе. Данные класса:

 string connStr = "server=localhost;user=root;password=root;database=jourl"; private BindingSource bindingSorce = new BindingSource();

Собственно, сам метод нажатия на кнопку:

private void button3_Click(object sender, EventArgs e)

Такой вопрос: какой из способов лучше? Читал, что лучше всего работать через .net коннектор с оф.сайта mysql. Задача — есть БД, структура которой никогда не изменяется. Нужно много разных клиентских приложений, которые будут делаться постоянно. Хотелось бы узнать, какая технология доступа к данным будет лучше и надежнее.

Регистрация: 25.08.2011
Сообщений: 2,841
Сообщение от sinj

Такой вопрос: какой из способов лучше? Читал, что лучше всего работать через .net коннектор с оф.сайта mysql. Задача — есть БД, структура которой никогда не изменяется. Нужно много разных клиентских приложений, которые будут делаться постоянно. Хотелось бы узнать, какая технология доступа к данным будет лучше и надежнее.

От Вашего BindingSource в данном случае толку никакого. Лишний узел для передачи таблицы. Ну в общем то дело Ваше.

По поводу «лучше», а кто сказал что .net коненктор лучше. Просто с ним удобнее всего работать. Вообще нету никакой разницы в адапторах. SQL один для всех. В любом случае все запросы вы будете делать через него.
А других способов подключения к базе данных кроме указанныго я не знаю, подскажите если кто найдет.

Skype — wmaster_s E-Mail — WorldMasters@gmail.com
Работаем по 3 критериям — быстро, качественно, недорого. Заказчик выбирает любые два.

WorldMaster
Посмотреть профиль
Найти ещё сообщения от WorldMaster

Пошаговое руководство. Отображение данных из базы данных SQL Server в элементе управления DataGrid

В этом пошаговом руководстве выполняется получение данных из базы данных SQL Server и их отображение в элементе управления DataGrid. С помощью ADO.NET Entity Framework можно создавать классы сущностей, представляющих данные, и использовать LINQ для записи запроса, который выполняет получение указанных данных из класса сущности.

Необходимые компоненты

Для выполнения этого пошагового руководства требуются следующие компоненты:

  • Visual Studio.
  • Доступ к запущенному экземпляру SQL Server или SQL Server Express с подключенной учебной базой данных AdventureWorks. Базу данных AdventureWorks можно загрузить из GitHub.

Создание новых классов сущностей

  1. Создайте проект приложения WPF на Visual Basic или C# с именем DataGridSQLExample .
  2. В обозревателе решений щелкните проект правой кнопкой мыши, выберите сначала Добавить, а затем Новый элемент. Откроется диалоговое окно Добавление нового элемента.
  3. В области «Установленные шаблоны» выберите Данные и в списке шаблонов выберите ADO.NET EDM (модель данных с использованием сущностей). ADO.NET Entity Data Model item template
  4. Назовите файл AdventureWorksModel.edmx , а затем щелкните Добавить. Появится мастер модели EDM.
  5. На экране «Выбор содержимого модели» выберите Конструктор EF из базы данных, а затем нажмите кнопку Далее.
  6. На экране «Выбор подключения к данным» укажите подключение к базе данных AdventureWorksLT2008. Дополнительные сведения см. в статье Диалоговое окно «Выбор подключения к данным». Проверьте, чтобы имя было AdventureWorksLT2008Entities и чтобы был установлен флажок у параметра Сохранить параметры соединения сущности в App.Config как:, после чего нажмите Далее.
  7. На экране «Выбор объектов базы данных» разверните узел «Таблицы» и выберите таблицы Product и ProductCategory. Вы можете создавать классы сущностей для всех таблиц; однако в этом примере данные извлекаются только из этих двух таблиц. Select Product and ProductCategory from tables
  8. Нажмите кнопку Готово. Сущности Product и ProductCategory отображаются в конструкторе сущностей. Product and ProductCategory entity models

Получение и представление данных

  1. Откройте файл MainWindow.xaml.
  2. Задайте для свойства Width элемента Window значение 450.
  3. В редакторе XAML добавьте следующий тег DataGrid между тегами и , чтобы добавить элемент DataGrid с именем dataGrid1 .

Window with DataGrid

  • Выберите Window.
  • С помощью меню свойств окна или редактора XAML создайте для элемента Window с именем Window_Loaded обработчик событий для события Loaded. Дополнительные сведения см. в разделе Практическое руководство. Создание простого обработчика событий. Ниже показан код XAML для файла MainWindow.xaml.

    Примечание. Если используется Visual Basic, в первой строке MainWindow.xaml замените x:Class=»DataGridSQLExample.MainWindow» на x:Class=»MainWindow» .

    using System.Data.Entity.Core.Objects; using System.Linq; using System.Windows; namespace DataGridSQLExample < /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window < AdventureWorksLT2008Entities dataEntities = new AdventureWorksLT2008Entities(); public MainWindow() < InitializeComponent(); >private void Window_Loaded(object sender, RoutedEventArgs e) < var query = from product in dataEntities.Products where product.Color == "Red" orderby product.ListPrice select new < product.Name, product.Color, CategoryName = product.ProductCategory.Name, product.ListPrice >; dataGrid1.ItemsSource = query.ToList(); > > > 
    Imports System.Data.Objects Class MainWindow Dim dataEntities As AdventureWorksLT2008Entities = New AdventureWorksLT2008Entities Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded Dim products As ObjectQuery(Of Product) = dataEntities.Products Dim query = _ From product In products _ Where product.Color = "Red" _ Order By product.ListPrice _ Select product.Name, product.Color, CategoryName = product.ProductCategory.Name, product.ListPrice dataGrid1.ItemsSource = query.ToList() End Sub End Class 

    DataGrid with data from SQL database

  • Запустите пример. Должен отображаться элемент DataGrid с данными.
  • См. также

    Совместная работа с нами на GitHub

    Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

    Вывод данных из БД в DataGridView

    не смог найти тему с ответом на мой вопрос. Есть база данных на локальном сервере MySql. Создаю приложение Windows Forms, соединение устанавливается с БД, но данные не выводятся в DataGridView. Точнее выводятся, но пишет System.Collections.Generic.List`1[System.String] за место данных и то только в 1-ом столбце. Не могу понять что это. Подскажите пожалуйста как мне сделать работоспособную программу Вот код соединения с БД. Метод public List[] Select() создаёт список для вывода.

    class DBconnect < private MySqlConnection connection; private string server, database, uid, password; public DBconnect() < Initialize(); >private void Initialize() < server = "localhost"; database = "catalog_personal"; uid = "root"; password = " "; string connectionString; connectionString = " SERVER =" + server + " ;" + " DATABASE =" + database + " ;" + " UID =" + uid + " ;" + "PASSWORD =" + password + " ;"; connection = new MySqlConnection(connectionString); >//Открываем соединение private bool OpenConnection() < try < connection.Open(); return true; >catch(MySqlException ex) < // При обработке ошибок вы можете основывать ответ вашего приложения // по номеру ошибки. // Два наиболее распространенных номера ошибок при подключении: // 0: не удается подключиться к серверу. // 1045: неверное имя пользователя и / или пароль. switch(ex.Number) < case 0: MessageBox.Show("Невозможно подключиться к серверу, " + "связаться с админ-панелью"); break; case 1045: MessageBox.Show("Неверное имя пользователя / пароль, " + "пожалуйста, попробуйте еще раз"); break; >return false; > > //Закрываем соединение private bool CloseConnection() < try < connection.Close(); return true; >catch (MySqlException ex) < MessageBox.Show(ex.Message); return false; >> public List[] Select() < string query = " SELECT * FROM personal"; //Создаем список для сохранения результа вывода List[] list = new List[4]; list[0] = new List(); list[1] = new List(); list[2] = new List(); list[3] = new List(); //Открываем соединение if (this.OpenConnection() == true) < //Создаем команду MySqlCommand cmd = new MySqlCommand(query, connection); //Создаем читатель данных и выполняем команду чтения MySqlDataReader dataReader = cmd.ExecuteReader(); while (dataReader.Read()) < list[0].Add(dataReader[0].ToString()); list[1].Add(dataReader[1].ToString()); list[2].Add(dataReader[2].ToString()); list[3].Add(dataReader[3].ToString()); >this.CloseConnection(); return list; > else < return list; >> > 

    Код в Form1

    public partial class Form1 : Form < public Form1() < InitializeComponent(); LoadData(); >private void LoadData() < DBconnect db = new DBconnect(); foreach (var s in db.Select()) < dataGridView1.Rows.Add(s); >> > 

    Результат ошибки

    Вот что получается в результате, прикрепляю скрин

    Отслеживать
    задан 7 ноя 2019 в 14:43
    33 1 1 золотой знак 1 1 серебряный знак 5 5 бронзовых знаков

    почему не использовать MySqlDataAdapter? Он сразу положит результат в DataTable. а его в свою очередь передадите в dataGridView1.DataSource. Select и LoadData будут из 2х строчек и соответственно без ошибок.

    7 ноя 2019 в 14:54

    Не разу не имел дело с DataAdapter, в программировании новичок. Если черканёте строчек кода, буду неимоверно признателен 🙂

    7 ноя 2019 в 15:10

    С адаптером может и удобно, но тогда ваш код получится жестко связанным с БД. Гибче подход работать все таки в парадигме ООП и создавать классы модели, т.е. вы должны создать класс Сотрудник и из БД извлекать и отображать список Сотрудников, а не массив стрингов или виртуальное зеркало таблицы БД коей является работа через адаптер.

    7 ноя 2019 в 15:23

    А работу через адаптер можно посмотреть в youtube, достаточно зайти на сайт и задать поиск c# mysql insert update delete и получите кучу индуского инглиша и разной степени паршивости примеров такой работы.

    7 ноя 2019 в 15:26
    Спасибо за совет, попробую разобраться. Если не разберусь, придётся заново открыть вопрос)))
    7 ноя 2019 в 15:44

    3 ответа 3

    Сортировка: Сброс на вариант по умолчанию

    Рассмотрим подробнее ваш пример. Вот вы «набросали» на форму контролы, и вам нужно начать программировать работу с ними. Что бы тут хотелось бы.

    Во-первых, не торопитесь сразу создавать БД и подключаться к ней. Для быстрого прототипирования приложения БД не нужна и даже вредна, т.к. отвлекает время и внимание на работу с ней.

    Во-вторых, в прил. необходимо выделить слои, минимально 3: слой отображения (визуальный интерфейс), слой модели предметной области с кот. работает ваше прил. и слой хранения (это как раз работа с БД).

    Начнем с создания модели. У нас модель достаточно простая. Я добавил еще статич. метод для клонирования экземпляра класса, зачем? Объясню ниже.

    public class Employee < public int Id < get; set; >//порядковый номер для отображения в DGV public int OrderNumber < get; set; >//имя public string FirstName < get; set; >//фамилия public string LastName < get; set; >public string Phone < get; set; >public Employee(int id, string firstName = "", string lastName = "", string phone = "") < FirstName = firstName; LastName = lastName; Phone = phone; >/// /// Получение клонированного экземпляра /// /// существующий экземпляр /// клон существующего сотрудника public static Employee GetClone(Employee employee) < if (employee is null) throw new System.ArgumentNullException(nameof(employee)); return new Employee(employee.Id) < FirstName = employee.FirstName, LastName = employee.LastName, Phone = employee.Phone, >; > public override string ToString() < return $": "; > > 

    Слой хранения начнем с абстракции, с создания интерфейса репозитория.

    public interface IEmployeeRepository < //получение всех Task>> GetEmployees(); //добавление Task> AddEmployee(Employee employee); //удаление Task> RemoveEmployee(int id); //обновление Task> UpdateEmployee(Employee emp); > 

    Здесь мы объявляем все нужные нам для работы методы. Кстати, вы можете начинать прямо с пустого интерфейса, и по мере надобности добавлять в него нужные члены. Обратите внимание, что предполагается работа в асинхронном режиме, и да, есть еще какой-то Result !

    Result — это пример т.н. монады, спец. класса для возвращения результата в случае если в методе возникнет ошибка или результат может быть равным null . Подробнее см.видео. Вот его код

    /// /// Монада Result для возвращения результата вместо null /// и для случаев когда возникает Exception, а результат из метода /// нужно возвращать какой-то /// /// public class Result  < public readonly T Value; public readonly string Error; //ctors public Result(T value) < Value = value; Error = String.Empty; >public Result(string error) < Error = error; >public bool HasValue => String.IsNullOrEmpty(Error); public static implicit operator bool(Result result) < return result.HasValue; >> 

    Теперь вернемся к интерфейсу приложения. Код формы такой

    public partial class MainForm : Form < //Источник данных для DGV private BindingSource _bsEmployees; //редактируемый сотрудник private BindingSource _bsCurrentEmployee; //работа с БД private IEmployeeRepository _repo; public MainForm() < InitializeComponent(); StartPosition = FormStartPosition.CenterScreen; Text = "Пример работы с MySql"; //установка привязок SetBindings(); this.Load += MainForm_Load; >private void MainForm_Load(object sender, EventArgs e) < //тестовый репозиторий _repo = new TestRepository(); //Загрузка данных LoadData(); //кнопки _buttonAdd.Click += ButtonAdd_Click; _buttonRemove.Click += ButtonRemove_Click; _buttonSave.Click += ButtonSave_Click; _buttonNext.Click += ButtonNext_Click; _buttonPrev.Click += ButtonPrev_Click; //клик по строке в DGV _dataGridViewEmployees.MouseClick += (s, a) =>SetCurrentEmployee(); > private void SetBindings() < _bsEmployees = new BindingSource(); _bsEmployees.DataSource = typeof(List); //привязки для DGV _dataGridViewEmployees.AutoGenerateColumns = false; _dataGridViewEmployees.DataSource = _bsEmployees; //привязки у столбцов _columnNumber.DataPropertyName = nameof(Employee.OrderNumber); _columnFirstName.DataPropertyName = nameof(Employee.FirstName); _columnLastName.DataPropertyName = nameof(Employee.LastName); _columnPhone.DataPropertyName = nameof(Employee.Phone); //текстбоксы _bsCurrentEmployee = new BindingSource(); _bsCurrentEmployee.DataSource = new List < new Employee(0) >; _textBoxFirstName.DataBindings.Add("Text", _bsCurrentEmployee, nameof(Employee.FirstName)); _textBoxLastName.DataBindings.Add("Text", _bsCurrentEmployee, nameof(Employee.LastName)); _textBoxPhone.DataBindings.Add("Text", _bsCurrentEmployee, nameof(Employee.Phone)); > private async void LoadData() < //получаем var result = await _repo.GetEmployees(); if (result) < //извлекаем Listemployees = result.Value; //пронумеровываем int i = 1; employees.ForEach(e => e.OrderNumber = i++); //отображаем _bsEmployees.DataSource = employees; _bsEmployees.MoveFirst(); SetCurrentEmployee(); > else < MessageBox.Show(result.Error, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); >> private void ButtonAdd_Click(object sender, EventArgs e) < //курсор на последнего _bsEmployees.MoveLast(); //след.порядковый номер int number = (_bsEmployees.Current as Employee).OrderNumber + 1; //добавляем нового _bsEmployees.Add(new Employee(0) < OrderNumber = number >); //выделяем его _bsEmployees.MoveNext(); SetCurrentEmployee(); //выделяем имя для редактирования _textBoxFirstName.Focus(); > private async void ButtonSave_Click(object sender, EventArgs e) < SwitchOnWaiting(); var current = (Employee)_bsCurrentEmployee.Current; Resultresult; try < if (current.Id == 0) < //добавляем нового сотрудника result = await _repo.AddEmployee(current); >else < //иначе обновляем существующего сотрудника result = await _repo.UpdateEmployee(current); >if (result) < //перечитываем данные LoadData(); >> finally < SwitchOffWaiting(); >if(!result) < MessageBox.Show(result.Error, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); >> private async void ButtonRemove_Click(object sender, EventArgs e) < SwitchOnWaiting(); //получаем текущего var employee = (Employee)_bsEmployees.Current; Resultresult; try < //удаляем из БД result = await _repo.RemoveEmployee(employee.Id); if (result) < //удаляем из отображения _bsEmployees.Remove(employee); _bsEmployees.MoveFirst(); SetCurrentEmployee(); >> finally < SwitchOffWaiting(); >if (!result) < MessageBox.Show(result.Error, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); >> private void ButtonPrev_Click(object sender, EventArgs e) < _bsEmployees.MovePrevious(); SetCurrentEmployee(); >private void ButtonNext_Click(object sender, EventArgs e) < _bsEmployees.MoveNext(); SetCurrentEmployee(); >private void SetCurrentEmployee() < if (_bsEmployees.Count >0) < _bsCurrentEmployee.List[0] = Employee.GetClone((Employee)_bsEmployees.Current); >else < _bsCurrentEmployee.List[0] = new Employee(0); >_bsCurrentEmployee.ResetItem(0); > private void SwitchOnWaiting() < foreach (var button in this.Controls.OfType()) < button.Enabled = false; >_dataGridViewEmployees.Enabled = false; Cursor = Cursors.WaitCursor; > private void SwitchOffWaiting() < foreach (var button in this.Controls.OfType()) < button.Enabled = true; >_dataGridViewEmployees.Enabled = true; Cursor = Cursors.Default; > > 

    На что хотелось бы обратить внимание.

    Работаем через привязки, используем для этого два экземпляра BindingSource , один для DataGridView , второй для текстбоксов текущего редактируемого или создаваемого нового сотрудника. По клику на DGV или переходе с пом.кнопок к следующему или предыдущему создается клон и привязывается текстбоксам. Сделано так для того, чтобы исключить одновременное изменение свойств выделенного сотрудника в DGV и пользователь понимал, что необходимо нажать кнопку Сохранить для запоминания изменений.

    В методе MainForm_Load() сделано подключение к фейковой БД _repo = new TestRepository(); или точнее классу реализующему IEmployeeRepository c тестовыми данными. Рассмотрим его

    class TestRepository : IEmployeeRepository < private List_employees; public TestRepository() < _employees = new List< new Employee(1, "Иван", "Голунов", "+7561234567"), new Employee(2, "Сергей", "Смирнов", "+77861234567"), new Employee(3, "Дарья", "Смирнова", "+798475563"), new Employee(4, "Кристина", "Семяжко", "+7304985023"), new Employee(5, "Владимир", "Драгунов", "+73431234567"), >; > public Task> GetEmployees() < var result = new List(); foreach (var e in _employees) < var emp = new Employee(e.Id, e.FirstName, e.LastName, e.Phone); result.Add(emp); >return Task.FromResult(new Result(result)); > public Task> AddEmployee(Employee employee) < if (employee is null) throw new ArgumentNullException(nameof(employee)); if (String.IsNullOrWhiteSpace(employee.FirstName) || String.IsNullOrEmpty(employee.FirstName)) < return Task.FromResult(new Result("Введите имя сотрудника.")); > if (String.IsNullOrWhiteSpace(employee.LastName) || String.IsNullOrEmpty(employee.LastName)) < return Task.FromResult(new Result("Введите фамилию сотрудника.")); > if (employee is null || employee.Id > 0) throw new ArgumentNullException(nameof(employee)); if (_employees.Count > 0) < employee.Id = _employees.Max(e =>e.Id) + 1; > else < employee.Id = 1; >_employees.Add(employee); return Task.FromResult(new Result(1)); > public Task> RemoveEmployee(int id) < if (id e.Id == id); if (emp != null) < _employees.Remove(emp); >return Task.FromResult(new Result(1)); > public Task> UpdateEmployee(Employee employee) < if (employee is null) throw new ArgumentNullException(nameof(employee)); if (String.IsNullOrWhiteSpace(employee.FirstName) || String.IsNullOrEmpty(employee.FirstName)) < return Task.FromResult(new Result("Введите имя сотрудника.")); > if (String.IsNullOrWhiteSpace(employee.LastName) || String.IsNullOrEmpty(employee.LastName)) < return Task.FromResult(new Result("Введите фамилию сотрудника.")); > var emp = _employees.FirstOrDefault(e => e.Id == employee.Id); if (emp != null) < emp.FirstName = employee.FirstName; emp.LastName = employee.LastName; emp.Phone = employee.Phone; >return Task.FromResult(new Result(1)); > > 

    Представьте на минутку, вы фрилансер и у вас заказ на подобную программу. Вам нужно быстро разработать прототип и предоставить заказчику, чтоб он мог этот прототип запустить и посмотреть, оценить и проч. Если бы вы использовали сразу подключение к реальной БД у вас бы возникли трудности, не правда ли. А так без проблем, компилируем и отправляем экзешник по почте.

    Заказчик доволен? 🙂 Пишем работу с реальной БД.

    class MySqlRepository : IEmployeeRepository < public MySqlRepository() < >private MySqlConnection GetConnection() < var cs = ConfigurationManager.ConnectionStrings["MySqlConn"].ToString(); var builder = new MySqlConnectionStringBuilder(cs); //чтоб избежать проблем с русским языком builder.CharacterSet = "utf8"; return new MySqlConnection(builder.ConnectionString); >public async Task>> GetEmployees() < var list = new List(); try < using (var con = GetConnection()) using (var cmd = con.CreateCommand()) < cmd.CommandText = "SELECT * FROM employees"; con.Open(); using (var reader = await cmd.ExecuteReaderAsync()) < while (await reader.ReadAsync()) < var emp = new Employee(reader.GetInt32(0)); emp.FirstName = reader.GetString(1); emp.LastName = reader.GetString(2); emp.Phone = reader.GetString(3); list.Add(emp); >> > > catch (MySqlException ex) < return new Result(GetUserFriendlyErrorMessage(ex)); > catch (Exception ex) < return new Result(ex.Message); > return new Result(list); > public async Task> AddEmployee(Employee employee) < if (employee is null) throw new ArgumentNullException(nameof(employee)); if (String.IsNullOrWhiteSpace(employee.FirstName) || String.IsNullOrEmpty(employee.FirstName)) < return new Result("Введите имя сотрудника."); > if (String.IsNullOrWhiteSpace(employee.LastName) || String.IsNullOrEmpty(employee.LastName)) < return new Result("Введите фамилию сотрудника."); > int result = 0; try < using (var con = GetConnection()) using (var cmd = con.CreateCommand()) < cmd.CommandText = "INSERT INTO employees (first_name, last_name, phone)" + " VALUES(@firstName, @lastName, @phone)"; cmd.Parameters.Add(new MySqlParameter("@firstName", MySqlDbType.VarChar, 200) < Value = employee.FirstName >); cmd.Parameters.Add(new MySqlParameter("@lastName", MySqlDbType.VarChar, 300) < Value = employee.LastName >); cmd.Parameters.Add(new MySqlParameter("@phone", MySqlDbType.VarChar, 45) < Value = employee.Phone ?? (object)System.DBNull.Value >); con.Open(); result = await cmd.ExecuteNonQueryAsync(); > > catch (MySqlException ex) < return new Result(GetUserFriendlyErrorMessage(ex)); > catch (Exception ex) < return new Result(ex.Message); > return new Result(result); > public async Task> RemoveEmployee(int id) < if (id ); con.Open(); result = await cmd.ExecuteNonQueryAsync(); > > catch (MySqlException ex) < return new Result(GetUserFriendlyErrorMessage(ex)); > catch (Exception ex) < return new Result(ex.Message); > return new Result(result); > public async Task> UpdateEmployee(Employee employee) < if (employee is null) throw new ArgumentNullException(nameof(employee)); if (String.IsNullOrWhiteSpace(employee.FirstName) || String.IsNullOrEmpty(employee.FirstName)) < return new Result("Введите имя сотрудника."); > if (String.IsNullOrWhiteSpace(employee.LastName) || String.IsNullOrEmpty(employee.LastName)) < return new Result("Введите фамилию сотрудника."); > int result = 0; try < using (var con = GetConnection()) using (var cmd = con.CreateCommand()) < cmd.CommandText = "UPDATE employees" + " SET first_name = @firstName, last_name = @lastName, phone = @phone" + " WHERE cmd.Parameters.Add(new MySqlParameter("@firstName", MySqlDbType.VarChar, 200) < Value = employee.FirstName >); cmd.Parameters.Add(new MySqlParameter("@lastName", MySqlDbType.VarChar, 300) < Value = employee.LastName >); cmd.Parameters.Add(new MySqlParameter("@phone", MySqlDbType.VarChar, 45) < Value = employee.Phone ?? (object)System.DBNull.Value >); cmd.Parameters.Add(new MySqlParameter("@id", MySqlDbType.Int32) < Value = employee.Id >); con.Open(); result = await cmd.ExecuteNonQueryAsync(); > > catch (MySqlException ex) < return new Result(GetUserFriendlyErrorMessage(ex)); > catch (Exception ex) < return new Result(ex.Message); > return new Result(result); > private string GetUserFriendlyErrorMessage(MySqlException ex) < var message = String.Empty; switch (ex.Number) < case 0: if (ex.InnerException.Message.Contains("Unknown")) < message = "Неверное название схемы или таблицы."; >else if (ex.InnerException.Message.Contains("Access")) < message = "Неверное имя или пароль доступа."; >else < message = ex.Message; >break; case 1042: message = "Сервер по указанному адресу не доступен." + "\nОшибка ожидания."; break; case 1045: message = "Неверное имя пользователя или пароль, " + "\nпожалуйста, попробуйте еще раз."; break; default: message = ex.Message; break; > return message; > > 

    В методе GetConnection() параметры соединения читаются из файла App.config

    Для работы с этим классом, нужно вернуться в код формы и в методе MainForm_Load() изменить строчку получения экземпляра репозитория _repo = new MySqlRepository(); .

    Да, и не забудьте сначала получить деньги от заказчика 🙂

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *