При выполнении в лабораторной работе упражнения №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
Упражнение 3. Хранение ресурсов в пользовательской библиотеке
Иногда возникает необходимость использовать одни и те же ресурсы во многих проектах. Чтобы их не копировать каждый раз в новые приложения, существует отличный способ упаковать ресурсы один раз в отдельную библиотечную сборку, которую можно будет подключать к любому приложению. В этом упражнении мы и познакомимся с таким способом. Нового здесь очень мало, многое мы уже знаем из предыдущего материала, поэтому сразу приступим.
Создание библиотеки ресурсов
- Командой меню File/Add/New Project оболочки добавьте к решению новый проект DLL -библиотеки с именем LibraryResource по шаблону WPF Custom Control Library
- В панели Solution Explorer переименуйте файл с дежурным именем CustomControl1.cs в CustomResources.cs
- Откройте файл CustomResources.cs на редактирование, ознакомтесь с инструкцией подключения библиотеки к исполнимой сборке и удалите ее из файла, чтобы не заслоняла будущий код
- Полностью удалите из класса CustomResources статический конструктор, который в данной задаче нам не пригодится (или не удаляйте, пусть болтается как есть)
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace LibraryResource { public class CustomResources : Control { /* // Статический конструктор в данной задаче не используется static CustomResources() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomResources), new FrameworkPropertyMetadata(typeof(CustomResources))); } //*/ } }
- Наполните класс CustomResources следующим кодом, определяющим ключи доступа к ресурсам
namespace LibraryResource { public class CustomResources : Control { // Статические поля (для разнообразия) public static readonly ComponentResourceKey Title1Key = new ComponentResourceKey(typeof(CustomResources), "Title1"); public static readonly ComponentResourceKey Title2Key = new ComponentResourceKey(typeof(CustomResources), "Title2"); // Добавили флаг для регулирования извлечения в элементах разметки public static bool changeResourceKeyFlag = true; // Добавляем статические свойства public static ComponentResourceKey ForegroundBrushKey { get { if (changeResourceKeyFlag) return new ComponentResourceKey( typeof(CustomResources), "ForegroundBrush1"); else return new ComponentResourceKey( typeof(CustomResources), "ForegroundBrush2"); } } public static ComponentResourceKey BackgroundBrushKey { get { if (changeResourceKeyFlag) return new ComponentResourceKey( typeof(CustomResources), "BackgroundBrush1"); else return new ComponentResourceKey( typeof(CustomResources), "BackgroundBrush2"); } } } }
- В автоматически созданной папке Themes откройте файл Generic.xaml и удалите из него заготовку контейнера <Style>...</Style> (имя файла зарезервировано и его менять нельзя!)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LibraryResource"> <Style TargetType="{x:Type local:CustomResources}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:CustomResources}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
Обратите внимание, что мастер оболочки автоматически сгенерировал оператор подключения пространства имен нашей библиотеки к разметке с псевдонимом local. Мы вольны изменить этот префикс на любой другой, но делать это ни к чему и будем в далнейшем использовать именно его для доступа к статическим свойствам класса CustomResources при определении наших ресурсов.
- Наполните ресурсный словарь <ResourceDictionary>...</ResourceDictionary> следующей разметкой определения ресурсов (окончательная разметка файла Generic.xaml приводится полностью)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LibraryResource"> <TextBlock x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=Title1}" TextAlignment="Center" Text="Группа кнопок 1" FontSize="14" FontWeight="Bold" FontFamily="Arial" FontStyle="Italic" TextDecorations="Underline" Foreground="DarkViolet" /> <SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=ForegroundBrush1}" Color="Blue" /> <ImageBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=BackgroundBrush1}" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 10 10" ImageSource="Images/FACE02.ICO" Opacity="0.5" /> <TextBlock x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=Title2}" TextAlignment="Center" Text="Группа кнопок 2" FontSize="14" FontWeight="Bold" FontFamily="Arial" FontStyle="Italic" TextDecorations="Underline" Foreground="DarkViolet" /> <SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=ForegroundBrush2}" Color="Red" /> <ImageBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=BackgroundBrush2}" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 24 24" ImageSource="Images/FACE04.ICO" Opacity="0.3" /> </ResourceDictionary>
В приведенной разметке мы использовали такие же ресурсы, что и в первом упражнении, чтобы не слишком напрягаться. Обратите внимание на новый синтаксис определения ключа. В атрибутах расширения разметки указана вся необходимая информация для синтаксического анализатора. Она указывает, в каком классе искать статическое свойство идентификатора ресурса и в каком пространстве имен текущей библиотечной сборки находится этот класс (об этом сообщает префикс).
В ресурсы мы поместили объекты, которые будем извлекать в исполнимом приложении при настройке интерфейсных элементов визуального дерева окна. Каждый из атрибутов визуальных элементов имеет свой тип и надеется извлечь ресурсный объект точно такого же типа.
- В панели Solution Explorer вызовите контекстное меню для проекта LibraryResource и выполните команду Build (или Rebuild ), чтобы откомпилировать проект и создать библиотечную сборку. Эта сборка неисполнимая, поэтому запускать проект на выполнение не следует, компилятор все равно выдаст ошибку
- В панели Solution Explorer выделите узел проекта LibraryResource и щелкните на пиктограмме Show All Files этой панели для раскрытия дерева файлов проекта
Мы видим, что оболочка откомпилировала проект и создала библиотечную сборку LibraryResource.dll, которую теперь можно использовать вместе с любой исполнимой сборкой для извлечения заложенных в нее ресурсов. Разумеется, в промышленных проектах следующим шагом следовало бы написать подробную инструкцию к пользованию этой библиотекой (выпустить документацию - почти как MSDN ), но мы этого делать не будем.