#006 Работа с изображениями / Стили в WPF
На примере предыдущего материала мы выяснили, что создание графики в WPF действительно реализовано просто. Однако, сложно представить работу с графикой без возможности использовать готовые изображения, подготовенные в других графических редакторах в форматах bmp, jpg, png, gif. Кстати, в дальнейших CTP мы получим "безграничную поддержку" нового формата Windows Media Photo.
Последний июньский CTP принес целый комплекс неожиданных проблем, связанных с работой с готовыми растрами. Многодневные обсуждения на форумах MSDN наконец выявили проблему неправильных компиляций и всевозможных ошибок, вроде не совпадения версий библиотеки PresentationCore.dll и других.
Прежде всего для устранения проблем нужно было установить новый WIC (см. статью № 001) , а также ознакомиться с новым синтаксисом и, как ни странно, ограничениями последнего билда. Так, например адресом изображения в этом CTP не может быть относительный путь, его нужно указывать в абсолютном виде. Отпал определитель LocalResource и так далее. Я не буду подробно заострять внимания на различиях May CTP Beta 2 и June CTP и расскажу о работе с изображениями на сегодняшний день.
Создаем новый проект типа WinFX Windows Application и даем ему имя "MyWpfImaging". Для начала поместим изображение на нашу форму. Для этого давайте добавим любое изображение к нашему проекту с помощью меню Visual Studio 2005 Project -> Add Existing Item. Выберите любое изображение. Я выбрал изображение 256x256 точек в формате png с именем Image.png:
После этой операции наше изображение стало "ресурсом" приложения. Давайте разместим его на форме. Контейнером для изображений является элемент <Image>, а свойство для указания файла - Source. Поэтому добавьте такой код внутрь вашего контейнера Grid:
<Image HorizontalAlignment ="Center"
VerticalAlignment ="Center"
Source ="Image.png"/>
В последнем June CTP локальный ресурс указывается вот так… просто? - я бы сказал запутывающе… но если вспомнить "замечательное" ограничение на относительные пути, то все становится на свои места.
Результат:
Чтобы разместить на форме не локальный ресурс, а некий файл на каком-либо носителе информации - просто укажите его адрес в абсолютной форме, например:
<Image HorizontalAlignment ="Center" VerticalAlignment ="Center"
Source ="C:\Image2.png"/>
Результат:
Давайте теперь сделаем что-нибудь менее тривиальное в рамках нашей темы. Замените контейнер Grid на контейнер WrapPanel. Этот контейнер размещает все элементы в одну строку с автоматическим переносом на следующую строку если количество элементов превышает емкость строки по ширине. Внесите такие коррективы в ваш код:
<WrapPanel >
<Image Height="48" Width ="48" Source ="Image.png"/>
<Image Height="48" Width ="48" Source ="Image.png"/>
<Image Height="48" Width ="48" Source ="Image.png"/>
<Image Height="48" Width ="48" Source ="Image.png"/>
<Image Height="48" Width ="48" Source ="Image.png"/>
</WrapPanel>
Посмотрите на работу контейнера WrapPanel:
В статье посвященной первому приложению на WPF мы говорили о том, что основной контейнер окна может содержать другие контейнеры - именно этим мы воспользуемся, чтобы окантовать каждое изобржение в рамку. Для этого есть специальный контейнер Border - этот контейнер может содержать только один элемент! Давайте применим его:
<Border BorderBrush ="Gold" BorderThickness ="3">
<Image Height="48" Width ="48" Source ="Image.png"/>
</Border>
Внесите этот код для каждого изображения и посмотрите на результат:
Минусом подобного подхода является то, что нам пришлось многократно дублировать один и тотже код. Сейчас мы рассмотрим способ унификации отображения элементов с одинаковым оформлением.
Для этого добавим секцию Window.Resources перед нашим контейнером WrapPanel:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MyWpfImaging" Height="300" Width="300"
>
<Window.Resources>
</Window.Resources>
Этот раздел служит для хранения различного типа ресурсов - в нашем случае мы создадим новый стиль для изображений и назовем его MyImg:
Наш стиль называется MyImg и может быть применен только к элементу типа Image (об этом говорит свойство TargetType). Давайте применим его к нашим изображениям:
<WrapPanel >
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
</WrapPanel>
Обратите внимание на синтаксис свойства Source!
Запустите программу и посмотрите на результат. Мы получили тот же эффект, что и в самом начале статьи, но, применив стили, мы придали нашему приложению профессиональный вид и обеспечили себя легкостью редактирвания кода. Если нам необходимо изменить внешний вид - мы просто редактируем стиль - и все элементы, ссылающиеся на этот стиль, подчиняются этим изменениям!
Полный листинг прграммы:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MyWpfImaging" Height="300" Width="300"
>
<Window.Resources>
<Style x:Key ="MyImg" TargetType ="Image">
<Setter Property ="Width" Value ="48"/>
<Setter Property ="Height" Value ="48"/>
<Setter Property ="Source" Value ="Image.png"/>
</Style>
</Window.Resources>
<WrapPanel >
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
<Image Style ="{StaticResource MyImg}"/>
</WrapPanel>
</Window>
Июль, 2006
По теме
- Создаем контекстно-зависимое WPF-приложение
- #024 – Знакомство с WPF/E
- #023 – Введение в WPF, reloaded…
- #022 Введение в Microsoft Interactive Designer RC1
- #021 Применение 3D в WPF - Часть 2
- #020 Применение 3D в WPF - Часть 1
- #019 Введение в возможности 3D на WPF
- #018 Размещение контрола NET 2.0 на форме WPF
- #017 Первое Web-приложение / Подробнее о Grid / Элемент Frame
- #016 EXE, XBAP, XAML? - Все равно!