#008 Эффекты в стиле Windows Vista — BitmapEffects и WPF

Автор: Topol Воскресенье, Май 6th, 2012 Нет комментариев

Рубрика: Операционные системы

Avalon содержмт множество средств оформления. Одними из таких средств являются растровые эффекты (Bitmap Effects). Они применимы практически к любому элементу WPF  и позволяют легко и быстро создавать свечение, размытие, выдавливание и другие эффекты. Если применить фантазию, можно приспособить эти эффекты для создания чего-то менее тривиального — например окна в стиле Windows Vista . Этим мы и займемся сегодня.

Создайте новый проект типа WinFX Windows Application и назовите его «MyVistaStyle».
Зададим свойства для формы, чтобы сделать ее прозрачной прямо в XAML-коде:

Код:
WindowStyle =»None» AllowsTransparency=»True» Background =»Transparent»

Далее разместим на форме прямоугольник — он и будет отвечать за внешний вид нашего окна:

Код:
<Rectangle HorizontalAlignment =»Stretch» VerticalAlignment =»Stretch»
Opacity =»0.9″
Stroke =»Gray»  Fill =»WhiteSmoke»
StrokeThickness =»1″
RadiusX =»5″ RadiusY =»5″/>

Увеличьте значения свойств Width и Height нашего окна Height=»480″ Width=»640″. Теперь давайте создадим загаловок окна. Для этого будем использовать хорошо знакомый вам по обычному программированию для .NET 2.0 — Label. Привожу полный код для сверки:

Код:
<Window x:Class=»Window1″
xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
Title=»MyVistaStyle» Height=»480″ Width=»640″
WindowStyle =»None» AllowsTransparency=»True» Background =»Transparent»
>
<Grid>
<Rectangle HorizontalAlignment =»Stretch» VerticalAlignment =»Stretch»
Opacity =»0.9″
Stroke =»Gray»  Fill =»WhiteSmoke»
StrokeThickness =»1″
RadiusX =»5″ RadiusY =»5″ />

<Label FontFamily =»SgoeUI» FontSize =»15″ Foreground =»Black»
Content =»Мое приложение в стиле Vista»
HorizontalAlignment =»Stretch» VerticalAlignment =»Top»
Margin =»10,10,0,0″
Name=»MyCaptionLabel» />
</Grid>
</Window>

Давайте посмотрим на результат:

Обратите внимание, что я задал для элемента Label имя MyCaptionLabel — я сделал это, чтобы дать возможность пользователю перетаскивать окно не за любою точку, а только за заголовок. Для этого добавьте обработчик события MouseLeftButtonDown для нашей надписи MyCaptionLabel и внесите в его тело код: Me.DragMove()

Запустите проект и убедитесь, окно теперь легко перемещается за заголовок. Теперь давайте займемся кнопками сворачивания, разворачивания и закрытия окна. Вы можете подготовить сами их изобржение в формате png, однако для того, чтобы вы легко выполнили задание этой статьи, я разместил небольшой архив с нужными изображениями тут.

Скачайте его и добавьте все содержащиеся в архиве изображения к ресурсам проекта (если вы затрудняетесь — прочтите статью № 006 ). Теперь давайте разместим их на форме:

Код:
<Image Source =»btnClose.png» Width =»44″ Margin =»0,2,2,0″
HorizontalAlignment =»Right» VerticalAlignment =»Top»/>

<Image Source =»btnMaximize.png» Width =»26″ Margin =»0,2,46,0″
HorizontalAlignment =»Right» VerticalAlignment =»Top»/>

<Image Source =»btnMinimize.png» Width =»26″ Margin =»0,2,72,0″
HorizontalAlignment =»Right» VerticalAlignment =»Top»/>

Посмотрите на результат:

Теперь придадим кнопкам функциональность. Для этого задайте им следующие имена: для первой Name=»myBtnClose» для второй Name=»myBtnMax» и для третьей Name=»myBtnMin». Перекомпилируйте проект и задайте для всех трех элементов обработчики уже давно знакомого события MouseLeftButtonDown. Давайте теперь внесем код (примеры на VB):

Код:
Для первой: Me.Close()
Для второй:
If Me.WindowState = Windows.WindowState.Maximized Then
Me.WindowState = Windows.WindowState.Normal
Else
Me.WindowState = Windows.WindowState.Maximized
End If
Для третьей: Me.WindowState = Windows.WindowState.Minimized

Запустите проект и убедитесь, что кнопки выполняют нужные функции.

Теперь давайте займемся оформлением уже подготовленных элементов! Сделаем наши кнопки похожими на кнопки окон Windows Vista. Для этого применим растровые эффекты. Добавьте такой код к определению изображения MyBtnClose:

Код:
<Image Source =»btnClose.png» Width =»44″ Margin =»0,2,2,0″
HorizontalAlignment =»Right» VerticalAlignment =»Top»
Name=»myBtnClose»>

<Image.BitmapEffect>
<OuterGlowBitmapEffect x:Name=»myOuterGlowBitMapEffect»
GlowColor=»Red» GlowSize=»0″ Noise=»0″
Opacity=»0.5″ />
</Image.BitmapEffect>

<Image.Triggers>
<EventTrigger RoutedEvent=»Mouse.MouseEnter»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect»
Storyboard.TargetProperty=»GlowSize»
To=»8″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent=»Mouse.MouseLeave»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect»
Storyboard.TargetProperty=»GlowSize»
To=»0″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>

Давайте разберемся, что и как тут работает. Прежде всего секция <Image.BitmapEffect> открывает доступ к различным растровым эффектам. Мы применим эффект внутреннего свечения при помощи определителя <OuterGlowBitmapEffect>. Именно этот эффект сделает нашу кнопку похожей на кнопку из Vista. Для того, чтобы кнопка «светилась изнутри» при наведении мыши и затухала, когда мышь покидает область кнопки, мы используем анимацию. Здесь все как обычно — свойство Triggers и две доски <Storyboard> — одна для события MouseEnter а другая для MouseLeave. Подробно объяснять не буду, так как мы рассматривали подобные анимации уже неоднократно. Скажу лишь, что анимации мы подвергаем свойство GlowSize нашего BitmapEffect-а.

Добавьте практически тотже самый код для двух других кнопок. Измените лишь свойство GlowColor на DodgerBlue для эффектов свечения, так как наши оставшиеся кнопки должны светиться не красным, а голубым цветом. Также не забудьте изменить имя для второго и третьего OuterGlowBitmapEffect с myOuterGlowBitMapEffect на какие-нибудь другие, чтобы не вызвать конфликта имен и подредактируйте ссылающиеся на них свойста TargetName. Думаю, вы справитесь без проблем.

Запускаем и смотрим на результат:

Обратите внимание, что кнопки не только светяться, но и обеспечивают плавные переходы, при движении мышью. Есть только один недостаток — наше свечение ограничивается верхней границей окна. Это легко исправить!

Дело в том, что наш прямоугольник, формирующий внешний вид окна, плотно прилегает к форме. Немного отредактируем свойства прямоугольника, чтобы он оставил небольшую зону перед верхней границей. Новые свойства прямоугольника:

Код:
Margin =»0,7,0,0″

Запускаем:

Уупс.. забыли про кнопки. Меняем свойства Margin для всех трех кнопок на такие:

Код:
Для первой: Margin =»0,9,2,0″
Для второй: Margin =»0,9,46,0″
Для третьей: Margin =»0,9,72,0″

Проверяем:

Посмотрите, какого замечательного эффекта мы смогли добиться!

В завершении статьи традиционно привожу полный листинг:

VB-листинг:

Код:
Partial Public Class Window1
Inherits Window

Public Sub New()
InitializeComponent()
End Sub

Private Sub MyCaptionLabel_MouseLeftButtonDown(ByVal sender As Object, _
ByVal e As System.Windows.Input.MouseButtonEventArgs)_
Handles MyCaptionLabel.MouseLeftButtonDown
Me.DragMove()
End Sub

Private Sub myBtnClose_MouseLeftButtonDown(ByVal sender As Object, _
ByVal e As System.Windows.Input.MouseButtonEventArgs) _
Handles myBtnClose.MouseLeftButtonDown
Me.Close()

End Sub

Private Sub myBtnMax_MouseLeftButtonDown(ByVal sender As Object, _
ByVal e As System.Windows.Input.MouseButtonEventArgs) _
Handles myBtnMax.MouseLeftButtonDown

If Me.WindowState = Windows.WindowState.Maximized Then
Me.WindowState = Windows.WindowState.Normal
Else
Me.WindowState = Windows.WindowState.Maximized
End If
End Sub
Private Sub myBtnMin_MouseLeftButtonDown(ByVal sender As Object, _
ByVal e As System.Windows.Input.MouseButtonEventArgs) _
Handles myBtnMin.MouseLeftButtonDown
Me.WindowState = Windows.WindowState.Minimized

End Sub
End Class

XAML-листинг:

Код:
<Window x:Class=»Window1″
xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
Title=»MyVistaStyle» Height=»480″ Width=»640″
WindowStyle =»None» AllowsTransparency=»True» Background =»Transparent»
>
<Grid>
<Rectangle Margin =»0,7,0,0″ HorizontalAlignment =»Stretch»
VerticalAlignment =»Stretch» Opacity =»0.9″
Stroke =»Gray»  Fill =»WhiteSmoke»
StrokeThickness =»1″ RadiusX =»5″ RadiusY =»5″ />

<Label FontFamily =»SgoeUI» FontSize =»15″ Foreground =»#FFFFFF»
Content =»Мое приложение в стиле Vista»
HorizontalAlignment =»Stretch» VerticalAlignment =»Top»
Margin =»10,10,0,0″
>
<Label.BitmapEffect >
<BlurBitmapEffect Radius=»10″ KernelType=»Gaussian» />
</Label.BitmapEffect>

</Label>

<Label FontFamily =»SgoeUI» FontSize =»15″ Foreground =»Black»
Content =»Мое приложение в стиле Vista»
HorizontalAlignment =»Stretch» VerticalAlignment =»Top»
Margin =»10,10,0,0″
Name=»MyCaptionLabel» />

<Image Source =»btnClose.png» Width =»44″ Margin =»0,9,2,0″
HorizontalAlignment =»Right» VerticalAlignment =»Top»
Name=»myBtnClose»>

<Image.BitmapEffect>
<OuterGlowBitmapEffect x:Name=»myOuterGlowBitMapEffect»
GlowColor=»Red» GlowSize=»0″ Noise=»0″
Opacity=»0.5″ />
</Image.BitmapEffect>
<Image.Triggers>
<EventTrigger RoutedEvent=»Mouse.MouseEnter»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect»
Storyboard.TargetProperty=»GlowSize»
To=»8″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent=»Mouse.MouseLeave»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect»
Storyboard.TargetProperty=»GlowSize»
To=»0″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>

<Image Source =»btnMaximize.png» Width =»26″ Margin =»0,9,46,0″
HorizontalAlignment =»Right» VerticalAlignment =»Top»
Name=»myBtnMax»>

<Image.BitmapEffect>
<OuterGlowBitmapEffect x:Name=»myOuterGlowBitMapEffect2″
GlowColor=»DodgerBlue» GlowSize=»0″
Noise=»0″
Opacity=»0.5″ />
</Image.BitmapEffect>
<Image.Triggers>
<EventTrigger RoutedEvent=»Mouse.MouseEnter»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect2″
Storyboard.TargetProperty=»GlowSize»
To=»8″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent=»Mouse.MouseLeave»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect2″
Storyboard.TargetProperty=»GlowSize»
To=»0″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>

</Image>

<Image Source =»btnMinimize.png» Width =»26″ Margin =»0,9,72,0″
HorizontalAlignment =»Right» VerticalAlignment =»Top»
Name =»myBtnMin»>

<Image.BitmapEffect>
<OuterGlowBitmapEffect x:Name=»myOuterGlowBitMapEffect3″
GlowColor=»DodgerBlue» GlowSize=»0″
Noise=»0″
Opacity=»0.5″ />
</Image.BitmapEffect>
<Image.Triggers>
<EventTrigger RoutedEvent=»Mouse.MouseEnter»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect3″
Storyboard.TargetProperty=»GlowSize»
To=»8″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent=»Mouse.MouseLeave»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»myOuterGlowBitMapEffect3″
Storyboard.TargetProperty=»GlowSize»
To=»0″ Duration=»0:0:0.2″ />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>

</Image >

</Grid>
</Window>

 

Источник: thevista.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты