При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Xna.Framework.Graphics;
namespace Application1 { public partial class MainForm : Form { // Объявим поле графического устройства для видимости в методах GraphicsDevice device;
public MainForm() { InitializeComponent();
// Подпишемся на событие Load формы this.Load += new EventHandler(MainForm_Load);
// Попишемся на событие FormClosed формы this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed); }
void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // Удаляем (освобождаем) устройство device.Dispose(); // На всякий случай присваиваем ссылке на устройство значение null device = null; }
void MainForm_Load(object sender, EventArgs e) { // Создаем объект представления для настройки графического устройства PresentationParameters presentParams = new PresentationParameters(); // Настраиваем объект представления через его свойства presentParams.IsFullScreen = false; // Включаем оконный режим presentParams.BackBufferCount = 1; // Включаем задний буфер // для двойной буферизации // Переключение переднего и заднего буферов // должно осуществляться с максимальной эффективностью presentParams.SwapEffect = SwapEffect.Discard; // Устанавливаем размеры заднего буфера по клиентской области окна формы presentParams.BackBufferWidth = this.ClientSize.Width; presentParams.BackBufferHeight = this.ClientSize.Height;
// Создадим графическое устройство с заданными настройками device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle, presentParams); }
protected override void OnPaint(PaintEventArgs e) { device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);
base.OnPaint(e); } } } Выбрасывается исключение: Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема? |
Разработка приложений ADO.NET для OLE DB
Добавление и удаление записей с использованием связанных элементов управления
В этом разделе мы добавим функциональность удаления или добавления по одной записи в редактируемую таблицу через второй поставщик данных. Как и при редактировании, будем использовать возможности объекта BidingContext формы и действовать через него на связанные с данными элементы управления.
- Добавьте на форму две кнопки и настройти их в соответствии с таблицей свойств
- Создайте обработчики события Click для обеих кнопок, которые заполните так
private void btnAdd_Click(object sender, EventArgs e) { // Добавить пустую запись в набор и // показать ее в элементах редактирования this.BindingContext[dataSet21, "Customers"].AddNew(); } private void btnDelete_Click(object sender, EventArgs e) { if (listBox.Items.Count <= 0)// Список пустой, удалять нечего return; // Отметить в наборе текущую запись как удаленную int index = this.BindingContext[dataSet21, "Customers"].Position; this.BindingContext[dataSet21, "Customers"].RemoveAt(index); SaveRecord();// Записать изменения в БД }
Теперь, когда мы ввели функциональность по изменению записей, начальное состояние флажка редактирования можно изменить для удобства
- Выделите флажок редактирования и установите его свойство checkEdit.Checked=true
Внешне окно запущенного приложения на данном этапе должно быть примерно таким
Если пользователь редактировал данные и забыл их сохранить, то при закрытии формы сохраним изменения сами.
- Выделите форму и создайте обработчик для ее события FormClosed, которое возбуждается при закрытии формы. В обработчик вставьте вызов функции сохранения данных
private void Form1_FormClosed(object sender, FormClosedEventArgs e) { SaveRecord(); }
Обработка возможных исключений при обращении к БД
Работа с БД подвержена внешним ошибкам, которые могут возникнуть при обращении к БД. Программист должен заготовить код на такой случай, чтобы необработанные исключения не поставили пользователя в тупик или повредили данные. Попробуйте в нашем приложении удалить какую нибудь родную запись БД Northwind, - будет выброшено необработанное исключение и приложение завершится аварийно.
Стандартным способом перехвата исключений и их обработки является применение механизма try... catch... finally. Последовательность блоков catch организует цепочку фильтров для отлавливания исключений в сторону увеличения их общего характера. Исключения средой исполнения выдаются в виде объектов-экземпляров классов, порожденных в конечном итоге от класса Exception. Мы воспользуемся перехватом специализированных объектов исключений типа OleDbException, поскольку именно они соответствуют типу возможных ошибок. Другие возможные исключения общего характера будем отлавливать самыми последними в цепочке фильтров.
В нашем проекте уязвимыми с точки зрения ошибок являются операции чтения данных из БД, сохранение и удаление записей. Ниже приведен полный листинг файла Form1.cs с кодом обработки ошибок
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Data.OleDb; namespace FormsADO { public partial class Form1 : Form { public Form1() { InitializeComponent(); } String ConnectionString(String fileNameNotExt) { string JetEngineString = @"Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Engine Type=5;Data Source="; string pathToFile = Application.StartupPath.ToString() + "\\Data\\"; return JetEngineString + pathToFile + fileNameNotExt.Trim() + ".mdb"; } private void Form1_Load(object sender, EventArgs e) { // Настраиваем объект команд oleDbSelectCommand1.CommandText = "SELECT CustomerID, CompanyName FROM Customers\r\n" + "WHERE (CompanyName LIKE ? + '%')"; oleDbSelectCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter()); oleDbSelectCommand1.Parameters[0].Value = "A"; // Задаем строку соединения oleDbConnection1.ConnectionString = ConnectionString("Northwind"); // Заполняем набор данных настроенным адаптером данных //oleDbDataAdapter1.Fill(dataSet11); SafeFill_1(); // Устанавливаем курсор списка в конец listBox.SelectedIndex = listBox.Items.Count - 1; } private void btnLoadList_Click(object sender, EventArgs e) { NewLoad(); } void NewLoad() { // Извлекаем значение текстового поля без пробелов String text = txtCustLimit.Text.Trim(); txtCustLimit.Text = text; // Сохраняем без пробелов для удобства oleDbSelectCommand1.Parameters[0].Value = text;// Устанавливаем значение параметра // Очищаем набор данных dataSet11.Clear(); // Заполняем набор данных командой с новым значением параметра //oleDbDataAdapter1.Fill(dataSet11); SafeFill_1(); // Устанавливаем курсор списка в конец listBox.SelectedIndex = listBox.Items.Count - 1; } private void txtCustLimit_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) NewLoad(); } private void listBox_SelectedIndexChanged(object sender, EventArgs e) { // Очистить второй набор данных dataSet21.Clear(); // Если выбран элемент списка, заполнить второй набор if (listBox.SelectedIndex != -1) { oleDbSelectCommand2.Parameters[0].Value = listBox.SelectedValue; //oleDbDataAdapter2.Fill(dataSet21); SafeFill_2(); } } private void txtCustomerID_KeyPress(object sender, KeyPressEventArgs e) { if(!checkEdit.Checked) e.Handled = true; } private void txtFax_KeyDown(object sender, KeyEventArgs e) { if(!checkEdit.Checked) e.Handled = true; } private void btnSave_Click(object sender, EventArgs e) { SaveRecord(); } private void SaveRecord() { // Применить свойство формы типа BindingContext // и вытолкнуть изменения со всех дочерних элементов формы, // связанных с данными, в кэш набора данных для заданной таблицы this.BindingContext[dataSet21, "Customers"].EndCurrentEdit(); // Обновить данные в БД из кэша набора данных dataSet21 //oleDbDataAdapter2.Update(dataSet21, "Customers"); SafeUpdate_2(); // Принять изменения // (лишнее!!! - вызывается автоматически методом Update) //dataSet21.AcceptChanges(); // Обновить первый набор данных и список listBox // с сохранением позиции выделенного элемента списка // на случай, если вдруг редактировалось поле CompanyName, // отображаемое в списке int index = listBox.SelectedIndex; NewLoad(); int count = listBox.Items.Count - 1; index = index < count ? index : count; // Однострочный условный оператор listBox.SelectedIndex = index; } private void btnCancel_Click(object sender, EventArgs e) { // Вытолкнуть первоначальные данные из // набора данных в поля редактирования this.BindingContext[dataSet21, "Customers"].CancelCurrentEdit(); } private void btnAdd_Click(object sender, EventArgs e) { // Добавить пустую запись в набор и // показать ее в элементах редактирования this.BindingContext[dataSet21, "Customers"].AddNew(); } private void btnDelete_Click(object sender, EventArgs e) { if (listBox.Items.Count <= 0)// Список пустой, удалять нечего return; // Отметить в наборе текущую запись как удаленную int index = this.BindingContext[dataSet21, "Customers"].Position; this.BindingContext[dataSet21, "Customers"].RemoveAt(index); SaveRecord();// Записать изменения в БД } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { SaveRecord(); } private void SafeFill_1() { try // Обработка ощибок { // Заполняем набор данных настроенным адаптером данных oleDbDataAdapter1.Fill(dataSet11); } catch (OleDbException ext) { string message = "Ошибка чтения данных из БД\n"; string caption = "Ошибка обращения к БД"; MessageBox.Show(String.Format(message + "Подробности: {0}", ext.Message), caption, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { oleDbConnection1.Close(); } } private void SafeFill_2() { try // Обработка ощибок { // Заполняем набор данных настроенным адаптером данных oleDbDataAdapter2.Fill(dataSet21); } catch (OleDbException ext) { string message = "Ошибка чтения данных из БД\n"; string caption = "Ошибка обращения к БД"; MessageBox.Show(String.Format(message + "Подробности: {0}", ext.Message), caption, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { oleDbConnection2.Close(); } } private void SafeUpdate_2() { try // Обработка ощибок { // Обновить данные в БД из кэша набора данных dataSet21 oleDbDataAdapter2.Update(dataSet21, "Customers"); } catch (OleDbException ext) { string message = "Ошибка записи данных в БД\n"; string caption = "Ошибка обращения к БД"; MessageBox.Show(String.Format(message + "Подробности: {0}", ext.Message), caption, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { oleDbConnection2.Close(); } } } }
Ниже приведены примеры окна сообщений для неверной строки соединения и для несоответствия данных типу поля:
Конечно, нужно было бы еще защитить методы объекта BindingContext, но это уже механическая работа и ее можно сделать самостоятельно.