|
При выполнении в лабораторной работе упражнения №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" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема? |
Привязка WPF к таблице данных ADO.NET
Упражнение 1. Привязка интерфейсных элементов к таблице ADO.NET базы данных OLE DB
Сейчас редкое приложение обходится без данных, хранящихся в центральном большом хранилище (Store - хранилище), - базе данных (БД). Такие приложения обычно называют управляемые данными. Их можно построить и по технологии WPF. Для взаимодействия с БД традиционно используются возможности объектов ADO.NET, а вот для отображения данных можно применить элементы и механизмы WPF, в том числе - привязку.
Главная трудность, которая нас ожидает при выполнении упражнений данной темы, - вспомнить классы ADO.NET и правильно их использовать. Такая ситуация естественна, пока не накопилось нужного количества практического опыта, а это дело наживное. Тем более, что необходимый для понимания данной темы минимум сведений по ADO.NET был изложен в начале этого курса, и к нему всегда, при необходимости, можно вернуться.
Начнем с привязки списковых элементов WPF к табличным объектам ADO.NET для простого просмотра. Нам нужно будет извлечь данные из БД и заполнить ими некоторый объект, способный автономно хранить добытые данные в оперативной памяти, не занимая при этом соединение с базой данных. Затем следует связать какой-нибудь списковый интерфейсный элемент WPF с этим объектом - источником данных.
В качестве хранилища данных будем использовать учебную базу данных Northwind.mdb типа OLE DB (Object Linking and Embedding Database). К такому типу БД относятся и базы файлового типа Microsoft Access с расширением .mdb (Microsoft Database). Наш выбор основан на том, что для таких баз не требуется устанавливать дополнительные программы, типа SQL Server.
Более того, в данном упражнении пока будем работать только с таблицей Employees БД Northwind.mdb (для единообразия). Постепенно перейдем и к другим таблицам, особенно при рассмотрении вопросов работы со взаимосвязанными таблицами БД, находящимися в отношении (Relations) "главная-подробности" (" master-detail ").
Для удобства, еще раз приведем схему, отображающую структуру БД Northwind.mdb, с которой мы ранее уже встречались
Прежде, чем двигаться дальше, уместно напомнить о существовании многоуровневого подхода к проектированию приложений, когда функциональные возможности, компоненты взаимодействия с пользователем и код проекта в целом искусственно делятся на отдельные логические уровни.
Уровней может быть несколько в зависимости от размера проекта, но обычно их бывает четыре. Об этом мы раньше говорили, но здесь еще раз вспомним:
- Хранилище данных (Data Store) - место, где хранятся сами структурированные данные. В нашем случае это MDF-файл
- Доступ к данным (Data Access Layer) - код, который необходим для извлечения и манипулирования необработанными данными. В нашем случае это классы ADO.NET и возможные пользовательские (программистские) надстройки над ними
- Бизнес-логика (Business Logic Layer) - код, который обрабатывает данные в соответствии с поставленной задачей для последующего представления их пользователю. Здесь учитывается специфика обрабатываемых данных и обеспечивается их целостность и непротиворечивость. Обычно, это основная часть ручной работы, которая полностью ложится на плечи программиста
- Представление данных/Пользовательский интерфейс (Presentation/Eser Interface Layer - UI) - код, который определяет, что именно пользователь должен видеть на экране. Сюда относятся визуальные элементы форматирования, сортировки и фильтрации данных, навигационные меню, списки, кнопки и другие интерактивные элементы управления
Очень часто границы между уровнями размыты, но все же надо их уметь распознавать или искусственно придумывать по какому-нибудь признаку, чтобы структурировать код приложения. Это дисциплинирует программиста, делает отдельные части кода более независимыми и уменьшает количество возможных ошибок. Старый методологический принцип - разделяй и властвуй (в данном случае - вертикаль власти), так хорошо помогающий нашему, порой еще слабосильному, сознанию.
Перечисленные уровни стремятся изолировать друг от друга, упаковывая код в отдельные файлы, динамические библиотеки, классы и пространства имен. Такой способ позволяет скрыть основную массу деталей и оставить только интерфейсные члены для взаимодействия с другими частями приложения. Подобным же образом намерены поступать и мы (клянемся!).
Подготовка проекта для выполнения упражнения
-
Командой File/New/Project создайте новое решение DataBindingTable с одноименным проектом
-
В панели Solution Explorer выделите корень проекта и командой Add/New Folder контекстного меню создайте подкаталог Data
-
Через контекстное меню панели Solution Explorer скопируйте из прилагаемой папки Source файл Northwind.mdb командой Add/Existing Item (измените фильтр диалогового окна на All Files). При появлении мастера Data Source Configuration Wizard отмените его кнопкой Cancel, поскольку мы пока не собираемся создавать типизированный набор данных
-
Выделите в панели Solution Explorer файл Northwind.mdb и через панель Properties проверьте, что его свойства имеют значение
- Build Action=Content
- Copy to Output Directory=Copy always
-
В панели Solution Explorer добавьте для корневого узла проекта командой Add/New Item заготовку файла конфигурации приложения с именем App.config
-
Заполните конфигурационный файл App.config кодом настройки строки соединения с БД, значение которой мы будем извлекать в процедурном коде во время выполнения приложения с помощью класса ConfigurationManager
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyNorthwind"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=|DataDirectory|\Data\Northwind.mdb"
providerName="System.Data.OleDb" />
</connectionStrings>
</configuration>-
В панели Solution Explorer вызовите для узла References проекта контекстное меню и командой Add Reference добавьте ссылку на библиотечную сборку System.Configuration.dll, в которой находится нужный нам класс ConfigurationManager для работы с конфигурационным файлом App.config из процедурного кода
-
Выделите в панели Solution Explorer узел проекта и добавьте к нему командой Project/Add Class новый файл с именем StoreNorthwindDB.cs
-
Добавьте в начало файла StoreNorthwindDB.cs строку подключения пространств имен инфраструктуры ADO.NET и заполните класс StoreNorthwindDB следующим кодом
using System;
using System.Collections.Generic;
using System.Text;
// Подключение пространств имен инфраструктуры ADO.NET
using System.Data;
using System.Data.OleDb;
using System.Windows;// Для MessageBox
namespace DataBindingTable
{
// Класс для доступа к БД
public class StoreNorthwindDB
{
// Извлекаем в поле строку соединения из файла App.config
String connectionString = System.Configuration.
ConfigurationManager.ConnectionStrings["MyNorthwind"].ConnectionString;
//*********************************************************
// Метод извлечения данных из таблицы Employees
// хранилища базы данных в ADO.NET-объект DataTable
//*********************************************************
DataTable dtEmployees = null;// Ссылка на объект DataTable
public DataTable LoadTableEmployees()
{
// Загрузим таблицу Employees только один раз
if (dtEmployees != null)
return dtEmployees;
// Заполняем объект таблицы Employees данными из БД
dtEmployees = new DataTable();
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
OleDbCommand selectCommand = conn.CreateCommand();
OleDbDataAdapter adapter = new OleDbDataAdapter(selectCommand);
// Загружает данные и схему таблицы Employees
selectCommand.CommandText = "SELECT EmployeeID, " +
"(LastName + ', ' + FirstName) AS FullName, " +
"Address, BirthDate, Region FROM Employees";
try
{
// Метод сам открывает БД и сам же ее закрывает
adapter.Fill(dtEmployees);
}
catch
{
MessageBox.Show("Ошибка подключения к БД");
}
finally
{
conn.Close(); // На всякий случай!
}
}
return dtEmployees;
}
}
}Инструкция using(), в которой создается соединение с БД, автоматически закроет его после выполнения своего блока кода, хотя то же самое сделает и метод adapter.Fill(). В SQL-запросе к БД наряду с извлечением столбцов оригинальных мы одновременно формируем вычислимый столбец FullName. Метод LoadTableEmployees(), который будет вызываться в клиенте класса, вернет ссылку на объект dtEmployees типа DataTable, загруженный данными таблицы.
Для того, чтобы получить только один экземпляр класса StoreNorthwindDB, и чтобы он был доступен во всех окнах приложения, разместим код его создания в классе App.
-
Откройте файл App.xaml.cs и добавьте в класс App уровня приложения следующий код
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Windows;
namespace DataBindingTable
{
public partial class App : Application
{
// Базовое поле для свойства
private static StoreNorthwindDB storeNorthwindDB =
new StoreNorthwindDB();
// Свойство для базового поля со ссылкой на экземпляр класса
public static StoreNorthwindDB StoreNorthwindDB
{
get { return storeNorthwindDB; }
}
}
}




