|
При выполнении в лабораторной работе упражнения №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
Добавление вычислимого столбца
Сейчас вычислимый столбец тоже можно добавить в нужную коллекцию объектной модели набора, но поскольку данные уже заполнены, придется заново перебрать все строки коллекции и присвоить придуманному столбцу требуемыми значениями. А можно поступить по другому: добавить в коллекцию набора ДО ЕГО ЗАПОЛНЕНИЯ новый столбец, настроить его схему требуемым образом, а потом загрузить коллекцию данными из хранилища. Вычислимый столбец сразу будет пересчитан налету и заполнен данными. При этом выражение SQL-запроса менять не придется. Проверим оба способа.
-
Верните свойство отображаемого столбца списка в прежнее значение DisplayMemberPath="FullName", где опять будет фигурировать имя несуществующего столбца коллекции Employees
-
Дополните метод ReadDataSet() следующими двумя закомментированными блоками кода, каждый из которых готов создать вычислимый столбец FullName
//*********************************************************
// Метод извлечения нетипизированного набора
// данных из хранилища данных Northwind.mdb
//*********************************************************
DataSet ds = null;// Ссылка на нетипизированный набор DataSet
public DataSet ReadDataSet()
{
// Загрузим набор данных только один раз
if (ds != null)
return ds;
ds = new DataSet();// Создаем множественный набор данных
// Заполняем множественный набор данных из БД
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
OleDbCommand selectCommand = conn.CreateCommand();
OleDbDataAdapter adapter = new OleDbDataAdapter(selectCommand);
/*//////////////////////////////////////
// Добавления вычислимого столбца в еще
// незаполненную коллекцию объектной модели
////////////////////////////////////////
// Готовим вычислимый столбец FullName
// для объекта-коллекции Employees
// ДО ЕЕ ЗАПОЛНЕНИЯ В НАБОРЕ ДАННЫХ !!!!!
ds.Tables.Add(new DataTable("Table"));// Дежурное имя по умолчанию
DataColumn column = new DataColumn("FirstName");
column.DataType = typeof(string);
ds.Tables[0].Columns.Add(column);
//
column = new DataColumn();
column.ColumnName = "LastName";
column.DataType = System.Type.GetType("System.String");
ds.Tables[0].Columns.Add(column);
//
column = new DataColumn("FullName", typeof(String));
column.Expression = "LastName + ', ' + FirstName";
ds.Tables[0].Columns.Add(column);
//*/////////////////////////////////////
// Загружаем всю таблицу Employees
selectCommand.CommandText = "SELECT * FROM Employees";
adapter.Fill(ds);// Сам открывает, загружает и закрывает
// Назначаем загруженным данным в наборе такое же имя,
// как и в хранилище, чтобы в дальнейшем не путаться
ds.Tables[0].TableName = "Employees";
// Загружает всю таблицу Customers
selectCommand.CommandText = "SELECT * FROM Customers";
// Назначаем загружаемым данным в наборе имя, в этом способе
// надо переопределить дежурное имя Table до заполнения набора
adapter.TableMappings.Add("Table", "Customers");// Должен стоять перед
adapter.Fill(ds); // Должен стоять после
// Загружает всю таблицу Orders
selectCommand.CommandText = "SELECT * FROM Orders";
// Загружаем и сразу этой порции данных назначаем имя в наборе
adapter.Fill(ds, "Orders");
/*//////////////////////////////////////
// Добавления вычислимого столбца в уже
// заполненную коллекцию объектной модели
////////////////////////////////////////
// Дублируем ссылку для удобства адресации
DataTable tableEmployees = ds.Tables["Employees"];
DataColumn column = new DataColumn("FullName");
column.DataType = typeof(string);
tableEmployees.Columns.Add(column);
// Приведем к верхнему регистру для различения
foreach (DataRow row in tableEmployees.Rows)
row[column] = row["LastName"].ToString().ToUpper() + ", " +
row["FirstName"].ToString().ToUpper();
//*/////////////////////////////////////
return ds;
}
}-
Раскомментируйте поочередно один из блоков (но не оба сразу!) создания вычислимого столбца и испытайте работу приложения. Быстрый способ раскомментировать любой из приведенных блоков - добавить слэш перед открывающей скобкой многострочного комментария (перед звездочкой)
При реализации любого из рассмотренных способов вкладка Page4 будет выглядеть так, как и ожидалось
Вкладка Page5. Прямая привязка элементов интерфейса к таблице Employees в DataSet
В предыдущем примере мы привязывали набор данных к именованному списку, а затем выделенный элемент SelectedItem списка назначали в свойстве DataContext сетки Grid. К этому SelectedItem привязывались текстовые поля TextBox. Объект SelectedItem менялся при выборе пользователя, а следом менялись и значения TextBox. В этом примере набор данных мы присвоим свойству DataContext именованного элемента Grid, чтобы его там нашел и список, и текстовые поля.
-
Добавьте к интерфейсной коллекции TabControl копию вкладки Page4 и преобразуйте ее во вкладку Page5 так
<!-- Прямая привязка элементов к набору данных DataSet -->
<TabItem Header="Page5">
<Grid Name="grid5"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox
Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
Margin="0,0,0,3"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Path=Employees}"
DisplayMemberPath="FullName"
IsSynchronizedWithCurrentItem="True"
/>
<TextBlock Grid.Row="1" Margin="0,0,5,0">EmployeeID:</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1"
Text="{Binding Path=Employees/EmployeeID, Mode=OneWay}"
Focusable="False"
/>
<TextBlock Grid.Row="2">FullName:</TextBlock>
<TextBox Grid.Row="2" Grid.Column="1"
Text="{Binding Path=Employees/FullName, Mode=OneWay}"
Focusable="False"
/>
<TextBlock Grid.Row="3">Address:</TextBlock>
<TextBox Grid.Row="3" Grid.Column="1"
Text="{Binding Path=Employees/Address, Mode=OneWay}"
Focusable="False"
/>
<TextBlock Grid.Row="4">BirthDate:</TextBlock>
<TextBox Grid.Row="4" Grid.Column="1"
Text="{Binding Path=Employees/BirthDate, Mode=OneWay}"
Focusable="False"
/>
<TextBlock Grid.Row="5">Region:</TextBlock>
<TextBox Grid.Row="5" Grid.Column="1"
Text="{Binding Path=Employees/Region, Mode=OneWay}"
Focusable="False"
/>
</Grid>
</TabItem>Мы назначили элементу Grid имя для возможности присвоения в процедурном коде его свойству DataContext ссылки на набор данных. Это будет единственный именованный элемент в разметке вкладки Page5, потому что другие элементы мы программировать в процедурном коде не будем. В списке ListBox мы оставили неизменными свойство Path=Employees, означающее таблицу набора в элементе Grid.DataContext, к которой привяжется список, и - отображаемый вычислимый столбец FullName.
Имя списка мы убрали, но добавили атрибут IsSynchronizedWithCurrentItem="True", который заставляет синхронизировать перемещение курсора в коллекции Employees набора данных со сменой выделенного пользователем элемента списка. Привязываемое к набору свойство Text элементов TextBox должно конкретизировать коллекцию в наборе Grid.DataContext вместе с адресуемым свойством привязки.
-
Добавьте в класс Window1 файла Window1.xaml процедурный код для инициализации источника привязки в именованной сетке Grid следующим образом
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Page1();
Page2();
Page3();
Page4();
Page5();
}
....................................................
#region Вкладка Page5
private void Page5()
{
// Назначаем источником набор данных DataSet в сетке
grid5.DataContext =
App.StoreNorthwindDB.ReadDataSet();
}
#endregion-
Запустите приложение - вкладка Page5 работает
-
Попробуйте убрать из списка атрибут IsSynchronizedWithCurrentItem="True" или заменить его значение на False - текстовые поля перестают отслеживать выделенные позиции списка: список и коллекция прекратили синхронную работу


