При выполнении в лабораторной работе упражнения №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" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема? |
Просмотр данных OLE DB средствами ADO.NET
Упражнение 7. Работа с объектом DataView
Объект DataView выполняет представление одних и тех же данных загруженной таблицы БД в нескольких разных форматах по принципу "Один документ - много представлений". DataView работает только с таблицей DataTable и готовит для отображения все ее столбцы без исключения. В присоединенном к таблице объекте DataView данные можно сортировать или задавать некоторые условия выборки строк представляемой таблицы. DataView физически не включает в себя данные отображаемой таблицы, он только изменяет их представление в элементе отображения "на лету".
Можно для одной таблицы заготовить несколько объектов DataView, каждый со своими настройками, и поочередно связывать их с элементом отображения. При этом в памяти компьютера будет находиться только одна копия данных, что существенно экономит ресурсы. Сам экземпляр объекта DataView можно настроить так, чтобы он запрещал редактирование данных связанной с ним таблицы, хотя в другом объекте такие ограничения на ту же самую таблицу могут отсутствовать. Операцию вставки, обновления или удаления данных в связанной таблице разрешают (запрещают) через свойства AllowNew, AllowEdit, AllowDelete. Если флаг AllowNew разрешает вставку, то новая строка добавляется в DataView методом AddNew().
При заполнении таблицы DataTable программно или данными БД строки отображаются в том порядке, в котором они были вставлены в таблицу или извлечены из БД. С любой таблицей уже связан один объект DataView, ссылка на который носит имя свойства DefaultView только для чтения. Через этот объект-представление мы можем сортировать представление данных таблицы и связывать элемент отображения не с самой таблицей, а с ее отсортированным представлением - объектом DefaultView.
Если встроенного представления нам мало, можно создать и настроить еще ряд объектов DataView и по мере надобности подключать их к свойству DataSource элемента отображения данных. Связанную с элементом отображения таблицу сортировать нельзя, как и сам связанный с таблицей элемент отображения. Но если между таблицей и элементом отображения имеется посредник DataView, то фильтрацию и сортировку отображаемых данных исходной таблицы можно выполнять через него.
У каждого элемента DataRow есть свойство RowState, в котором ведется история состояния строки при ее редактировании. Это свойство автоматически принимает одно из значений перечисления DataRowState при выполнении действий над строкой:
- Detached - строка только что создана методом DataTable.NewRow(), но еще не добавлена в таблицу методом DataTable.Rows.Add()
- Added - строка добавлена в коллекцию таблицы, но не помечена как окончательно принятая один из методов: DataRow.AcceptChanges(), DataTable.AcceptChanges(), DataSet.AcceptChanges()
- Deleted - строка помечена как удаленная из таблицы методом DataRow.Delete(), но не принята окончательно методом AcceptChanges()
- Modified - строка была изменена, но еще не принята
- Unchanged - строка не изменилась со времени последнего вызова AcceptChanges()
Объектная модель таблицы хранит несколько версий одной и той же строки. Эти версии строки зависят от того, применялся или нет к ней метод AcceptChanges(). Значения версий определяются перечислением DataRowVersion и могут иметь значения: Current, Default, Original, Proposed. Какие версии имеет строка, можно проверить с помощью ее метода DataRow.HasVersion(DataRowVersion), например, следующий код распечатает все существующие версии указанной строки
void CheckVersion(DataRow row) { if (row.HasVersion(DataRowVersion.Current)) Console.WriteLine("Версия Current"); if (row.HasVersion(DataRowVersion.Default)) Console.WriteLine("Версия Default"); if (row.HasVersion(DataRowVersion.Original)) Console.WriteLine("Версия Original"); if (row.HasVersion(DataRowVersion.Proposed)) Console.WriteLine("Версия Proposed"); }
Указанные версии строки связаны с ее редактированием и вызовом метода AcceptChanges() объектов DataRow, DataTable или DataSet следующим образом:
- После вызова метода DataRow.BeginEdit(), если значение строки будет изменено, станут доступными версии Current и Proposed (текущий и предложенный)
- После вызова метода DataRow.CancelEdit() будет удалена версия Proposed
- После вызова метода DataRow.EndEdit() версия Proposed становится версией Current
- После вызова метода DataRow.AcceptChanges() версия Proposed становится версией Current ; версия Original не изменяется
- После вызова метода DataTable.AcceptChanges() версия Original становится идентичной версии Current
- После вызова метода DataTable.RejectChanges() (- отклонить изменения) версия Original становится версией Current
Объект DataView имеет свойства, позволяющие управлять представляемыми данными:
-
RowFilter - позволяет задать критерий выбора представляемых строк, например
RowFilter="Price < 10"; RowFilter="LastName LIKE ' W%' "; RowFilter="ProductID = 1"
-
RowStateFilter - позволяет выбирать строки, находящиеся в определенном
состоянии. Значение этого свойства определяется перечислением System.Data.DataViewRowState:
- Added - новые строки
- CurrentRows - текущие строки, включая неизмененные, новые и модифицированные
- Deleted - строки, помеченные как удаленные
- ModifiedCurrent - ближайшая модифицированная версия данных, полученная из ModifiedOriginal
- ModifiedOriginal - предыдущая версия данных, из которой получена версия ModifiedCurrent
- None - пустое значение
- OriginalRows - первоначальные строки, загруженные из БД
- Unchanged - строка не менялась
Например, следующая функция настраивает DataView на представление строк таблицы предыдущего или следующего состояния модификации
DataView ViewChanges(DataTable table, bool viewCurrent) { DataView view = table.DefaultView; if (viewCurrent == true) view.RowStateFilter = DataViewRowState.ModifiedCurrent; else view.RowStateFilter = DataViewRowState.ModifiedOriginal; return view; }
- Sort - это свойство указывает порядок сортировки представляемых данных, например Sort="FullName ASC" ; Sort="FullName DESC" ; - сортируют в прямом и обратном порядке представление таблицы по полю FullName
Объект DataView имеет два метода поиска данных для выборки в представление, оба из которых осуществляют поиск в отсортированном (в свойстве Sort ) столбце по заданному критерию:
- DataView.Find() - ищет первое вхождение строки в DataView и возвращает номер строки, или -1
- DataView.FindRows() - ищет массив строк и возвращает его, или пустой массив
В данном упражнении элементы отображения мы свяжем не напрямую с таблицей, заполненной данными, а с промежуточным объектом DataView, в котором легко можно менять представления данных пользователю. В коде попробуем продемонстрировать основные возможности объекта DataView. В режиме проектирования интерфейса установим простейшие настройки его элементов, а остальное выполним динамически в коде приложения.
- Добавьте в решение новый проект с именем WinForms7 и оформите интерфейс пользователя в соответствии с таблицей
Объект | Свойство | Значение | Пояснения |
---|---|---|---|
Form | Text | Упражнение 7 | Заголовок окна |
MaximizeBox | False | Запретить системную кнопку | |
Panel | Dock | Top | Верхний контейнер для Label и ComboBox |
Panel | Dock | Fill | Нижний контейнер для DataGrid |
Label | Text | Letter: | Объекты Label и ComboBox поместите в верхний контейнер Panel |
ComboBox | (Name) | cbLetters | Для размещения букв латинского алфавита |
FlatStyle | Flat | Плоский стиль элемента | |
Label | Text | Column: | |
ComboBox | (Name) | cbColumns | Для размещения имен столбцов |
DataGrid | (Name) | dataGrid | Объект DataGrid поместите в нижний контейнер Panel |
AllowSorting | False | Запретить сортировку столбцов через DataGrid | |
CaptionText | Представления таблицы Customers | Заголовок DataGrid | |
Dock | Fill | Развернуть на весь контейнер Panel | |
ReadOnly | True | Запретить редактирование данных |
- Модифицируйте файл 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; using System.Data.Common; namespace WinForms7 { public partial class Form1 : Form { public Form1() { InitializeComponent(); // Подписка на события ComboBox общего обработчика cbLetters.SelectedIndexChanged += Combo_SelectedIndexChanged; cbColumns.SelectedIndexChanged += Combo_SelectedIndexChanged; // Загрузки объектов данными LoadCustomers(); LoadLetters(); LoadColumns();// Вызывать после загрузки данных LoadCustomers() } // Строка соединения к БД с абсолютным путем, определяемым сборкой String ConnectionString() { // Используем построитель строки подключения OleDbConnectionStringBuilder objConnectionStringBuilder = new OleDbConnectionStringBuilder(); objConnectionStringBuilder.Provider = "Microsoft.Jet.OLEDB.4.0"; objConnectionStringBuilder.DataSource = Application.StartupPath.ToString() + @"\Data\Northwind.mdb"; return objConnectionStringBuilder.ToString(); } DataTable tableCustomers;// Поле, видимое в методах void LoadCustomers() { // Формируем поставщик OleDbCommand selectCommand = new OleDbCommand(); selectCommand.CommandText = "SELECT * FROM Customers";// Будем читать все столбцы selectCommand.Connection = new OleDbConnection(ConnectionString()); selectCommand.CommandType = CommandType.Text;// По умолчанию OleDbDataAdapter adapter = new OleDbDataAdapter(selectCommand); // Создаем объект таблицы tableCustomers = new DataTable(); // Заполняем таблицу adapter.Fill(tableCustomers); // Адресуемся к встроенному в таблицу представлению DataView defaultView = tableCustomers.DefaultView; // Связываем встроенное представление с элементом отображения dataGrid.DataSource = defaultView; } void LoadLetters() { // Добавили первый элемент списка cbLetters.Items.Add("All"); // Дополняем список буквами алфавита for (char ch = 'A'; ch <= 'Z'; ch++) { cbLetters.Items.Add(ch); } // Устанавливаем на первый индекс cbLetters.SelectedIndex = 0; } void LoadColumns() { // Создаем временную таблицу для имен столбцов DataTable tableTmp = new DataTable(); // Добавляем один столбец для хранения имен столбцов tableTmp.Columns.Add("ColumnName", typeof(String)); // Заполняем временную таблицу именами столбцов исходной таблицы for (int i = 0; i < tableCustomers.Columns.Count; i++) { tableTmp.Rows.Add(tableCustomers.Columns[i].ColumnName); } // Создаем представление по единственному столбцу DataView view = new DataView(tableTmp); // Связываем представление с элементом отображения cbColumns.DataSource = view; cbColumns.DisplayMember = "ColumnName"; // Ищем нужное имя и позиционируем список view.Sort = "ColumnName";// Сортируем для списка имен столбцов int selectedIndex = view.Find("CustomerID");// По отсортированному можно cbColumns.SelectedIndex = selectedIndex;// Позиционируем программно на CustomerID } private void Combo_SelectedIndexChanged(object sender, EventArgs e) { // Еще не созданы if (cbLetters == null || cbColumns == null) return; // Еще ничего не выбрано if (cbLetters.SelectedIndex == -1 || cbColumns.SelectedIndex == -1) return; // Извлекаем символ из cbLetters String letter = cbLetters.SelectedItem.ToString(); if (letter == "All") letter = String.Empty; // Извлекаем из cbColumns, связанного с DataView, выбранное имя столбца Object obj = cbColumns.SelectedItem; String columnName = ((DataRowView)obj).Row["ColumnName"].ToString(); // Создаем для таблицы Customers объект представления и настраиваем его DataView view = new DataView(tableCustomers); view.RowFilter = "CustomerID LIKE '" + letter + "%'"; view.Sort = columnName; // Связываем настроенное представление с объектом отображения dataGrid.DataSource = view; } } }
- Запустите приложение и проверьте его функциональность