Опубликован: 11.09.2006 | Уровень: специалист | Доступ: свободно
Лекция 4:

Работа с данными

Связывание элементов управления с данными

Представление данных в виде таблицы на форме достаточно удобно в ряде случаев. Можно сразу просматривать большое количество записей. Однако для постоянного внесения изменений в базу данных более удобным будет представление записей индивидуально, когда значение каждого поля находится в отдельном текстовом поле. Проект DataWizardMDB, рассмотренный в начале этой лекции, и представляет собой подобную форму.

Создайте новый проект. Назовите его DataTextBox. Переходим на вкладку Data панели инструментов Toolbox и перетаскиваем oleDbDataAdapter. В запустившемся мастере устанавливаем подключение к файлу Microsoft Access RBProduct.mdb. В свойствах oleDbDataAdapter1 на информационной панели нажимаем Generate Dataset. Называем его dsProvider. Переходим в код формы и подключаем пространство имен:

using System.Data.OleDb;

В конструкторе формы после InitializeComponent вызываем метод Fill объекта oleDbDataAdapter:

oleDbDataAdapter1.Fill(dsProvider);

Переключаемся в режим дизайна. Располагаем на форме Label и TextBox. В свойстве Text элемента label вводим "Поставщик", в этом же свойстве элемента textBox оставляем пустую строку.

Щелкаем на знак (+) свойства DataBindings элемента управления textBox. В значении поля Text этой группы снова щелкаем на знак (+) около элемента dsProvider и выбираем поле "Поставщик" (рис. 4.51).

Связывание элемента textBox с данными

Рис. 4.51. Связывание элемента textBox с данными

Запускаем приложение. Теперь в текстовое поле выводится первое значение столбца "Поставщик" (рис. 4.52).

Готовая форма

Рис. 4.52. Готовая форма

На диске, прилагаемом к книге, вы найдете проект DataTextBox (Code\Glava4\ DataTextBox).

Теперь рассмотрим связывание элементов управления с данными, осуществляемое программным образом. Создайте новый проект. Назовите его DataBindings.На создавшейся форме располагаем по четыре элемента TextBox и Label (рис.рис. 4.53):

Расположение элементов на форме

Рис. 4.53. Расположение элементов на форме

Текстовым полям, расположенным напротив надписей, устанавливаем свойство Name следующим образом:

  • "Адрес поставщика" — txtAddress
  • "Код поставщика" — txtID
  • "Поставщик" — txtProvider
  • "Телефон" — txtPhone.

Далее подключаем пространство имен:

using System.Data.OleDb;

Задаем строки подключения:

string commandText = "SELECT [Адрес поставщика], [Код поставщика], Поставщик, 
Телефон FROM Поставщики";
string connectionString = @"Provider=""Microsoft.Jet.OLEDB.4.0"";Data 
Source=""D:\Uchebnik\Code\Glava4\RBProduct.mdb"";User ID=Admin;Jet OLEDB:Encrypt 
Database=False";
Листинг 4.19.

Устанавливаем соединение и определяем все необходимые объекты:

OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
OleDbCommand myCommand = new OleDbCommand();
myCommand.Connection = conn;
myCommand.CommandText = commandText;
OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
dataAdapter.SelectCommand = myCommand;
DataSet ds = new DataSet();
dataAdapter.TableMappings.Add("Table", "Поставщики");
dataAdapter.Fill(ds);

Для связывания свойства Text текстового поля txtAddress с полем "Адрес поставщика" таблицы "Поставщики" используем код:

txtAddress.DataBindings.Add("Text", ds, "Поставщики.Адрес поставщика");
Листинг 4.20.

Аналогично для других текстовых полей:

txtID.DataBindings.Add("Text", ds, "Поставщики.Код поставщика");
txtPhone.DataBindings.Add("Text", ds, "Поставщики.Поставщик");
txtProvider.DataBindings.Add("Text", ds, "Поставщики.Телефон");

Обратите внимание на названия соответствующих столбцов. На практике вы никогда не встретите названий столбцов таблицы базы данных, содержащих пробелы между слов и к тому же на кириллице — это нонсенс. В нашем учебном проекте тем не менее все работает. Почему? Дело в том, что среда Visual Studio .NET поддерживает кодировку Unicode, поэтому теоретически названия переменных и объектов можно давать на русском языке. Вы можете убедиться в этом, переименовав, скажем переменную connectionString в "строкаПодключения" а ds в "ДатаСет"и запустить приложение – все будет работать. Но если мы будем создавать коммерческое приложение, которое должно будет работать в самых разных условиях, подобный код, сам по себе, может стать источником многочисленных ошибок. Поэтому давать названия на кириллице не следует. Для ясности изложения, однако, оставим названия столбцов как есть.

Закрываем соединение:

conn.Close();

Запускаем приложение. В текстовых полях выводится соответствующая информация.

Перемещение по записям. Объект CurrencyManager

При выводе данных в виде отдельных записей необходимо реализовать возможность перемещения по записям. Это можно сделать с помощью экземпляра класса CurrencyManager, обеспечивающего функционирование связывания с данными. Располагаем на форме четыре кнопки и надпись в ряд следующим образом (рис. 4.54):

Расположение кнопок

Рис. 4.54. Расположение кнопок

Устанавливаем следующие свойства элементов управления:

Элемент Name Text
Кнопка btnFirst |<
Кнопка btnPrevious <
Кнопка btnNext >
Кнопка btnLast >|
Надпись lblRecordsPosition

Объявляем экземпляр cmRecords класса CurrencyManager ( в классе Form1):

CurrencyManager cmRecords;

В конструкторе формы Form1 связываем созданный объект cmRecords с таблицей "Поставщики" объекта ds:

cmRecords = (CurrencyManager)BindingContext[ds, "Поставщики"];

Создаем обработчики для событий ItemChanged и PositionChanged объекта cmRecords:

cmRecords.ItemChanged+=new ItemChangedEventHandler(cmRecords_ItemChanged);
cmRecords.PositionChanged+=new EventHandler(cmRecords_PositionChanged);
Листинг 4.21.

Вызываем метод, отображающий навигацию по записям:

DisplayRecordsPosition();

Создаем этот метод:

private void DisplayOrdersPosition()
  {
  lblRecordsPosition.Text = "Запись" + (cmRecords.Position + 1) +
+ "из" + cmRecords.Count;
  }
Листинг 4.22.

Добавляем методы, вызывающие метод DisplayOrdersPosition() в случае наступления событий ItemChanged и PositionChanged:

private void cmRecords_ItemChanged( object sender, ItemChangedEventArgs e)
  {
    DisplayRecordsPosition();
  }
private void cmRecords_PositionChanged( object sender, System.EventArgs e)
  {
    DisplayRecordsPosition();
  }
Листинг 4.23.

Добавляем обработчиков для нажатий навигационных кнопок:

private void btnFirst_Click(object sender, System.EventArgs e)
  {
    cmRecords.Position = 0;
  }
  
private void btnPrevious_Click(object sender, System.EventArgs e)
  {
    cmRecords.Position--;
  }

private void btnNext_Click(object sender, System.EventArgs e)
  {
    cmRecords.Position++;
  }

private void btnLast_Click(object sender, System.EventArgs e)
  {
    cmRecords.Position = cmRecords.Count - 1;
  }

Запускаем приложение. Теперь можно перемещаться по записям (рис. 4.55).

Форма с навигационными кнопками

Рис. 4.55. Форма с навигационными кнопками
Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/