Окна необычной формы часто являются товарным знаком современных прикладных приложений вроде редакторов фотографий, программ для создания кинофильмов и МРЗ-проигрывателей; скорее всего, они будут встречаться в WPF-приложениях даже более часто.
В создании базового приложения нестандартной формы в WPF нет ничего сложного. Однако создание привлекательного профессионально выглядящего окна необычной формы требует немалых усилий — и, нередко, привлечения талантливого дизайнера графики для создания эскизов и фоновой графики.
Базовая процедура для создания окна нестандартной формы подразумевает выполнение следующих шагов:
- Установите для свойства Window.AllowsTransparency значение true.
- Установите для свойства Window.WindowStyle значение None, чтобы скрыть не клиентскую область окна (рамку голубого цвета). Если этого не сделать, при попытке показать окно появится ошибка InvalidOperationException.
- Установите для фона (свойства Background) прозрачный цвет (цвет Transparent, значение альфа-канала которого равно нулю). Или же сделайте так, чтобы для фона использовалось изображение, имеющее прозрачные области (с нулевым значением альфа-канала).
Эти три шага эффективно удаляют стандартный внешний вид окна. Для обеспечения эффекта окна необычной формы далее необходимо предоставить какое-то непрозрачное содержимое, имеющее нужную форму. Здесь возможны перечисленные ниже варианты:
- Предоставить фоновую графику, используя файл такого формата, который поддерживает прозрачность. Например, для фона можно использовать файл PNG. Это простой прямолинейный подход, и он очень удобен, если приходится работать с дизайнерами, которые не разбираются в XAML. Однако из-за того, что окно будет визуализироваться с большим количеством пикселей и более высокими системными параметрами DPI фоновая графика может приобрести искаженный вид. Это также может представлять проблему и в случае разрешения пользователю изменять размеры окна.
- Использовать доступные в WPF функции для рисования формы, чтобы создать фон с векторным содержимым. Такой подход исключает потерю качества, какими бы ни были размеры окна и настройка DPI системы. Однако в этом случае наверняка потребуется использовать средство проектирования, поддерживающее XAML, такое как Expression Blend.
- Использовать более простой WPF-элемент, имеющий необходимую форму. Например, окно с замечательными скругленными углами можно создать с помощью элемента Border. Такой подход позволяет создавать окна с современным внешним видом в стиле Office без применения каких-либо дизайнерских навыков.
Ниже в качестве примера приведен код создания пустого прозрачного окна с применением первого подхода и предоставлением файла PNG для прозрачных областей:
<Window x:Class="Windows.TransparentBackground"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Windows" Height="300" Width="300"
WindowStyle="None" AllowsTransparency="true"
MouseLeftButtonDown="window_MouseLeftButtonDown"
>
<Window.Background>
<ImageBrush ImageSource="shapes.png"></ImageBrush>
</Window.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Margin="20">A Sample Button</Button>
<Button Margin="20" Grid.Row="2" Click="cmdClose_Click">Close</Button>
</Grid>
</Window>
Это окно необычной формы (состоящее из окружности и квадрата) имеет не только пробелы, сквозь которые может просматриваться находящееся за ним содержимое, но кнопки, которые выходят за границы изображения и накладываются на прозрачную область, из-за чего кажется, будто бы они существуют сами по себе, без окна:
Те, кому приходилось программировать с использованием Windows Forms ранее, наверняка заметят, что окна нестандартной формы в WPF имеют более четкие края, особенно на изгибах. Все дело в том, что WPF умеет выполнять сглаживание между фоном окна и находящимся за ним содержимым для создания более гладкого края.
Ниже показано другое, более простое окно необычной формы. В этом окне используется элемент Border со скругленными углами для придания окну отчетливого внешнего вида. Компоновка тоже является упрощенной, поскольку исключает случайный выход содержимого за пределы границы, а размер границы может легко изменяться без наличия элемента Viewbox:
<Window x:Class="_27___Window.UnrealWindow"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="UnrealWindow" Height="300" Width="300" x:Name="MyWindow"
AllowsTransparency="True" Background="Transparent" WindowStyle="None">
<Grid>
<Border Width="auto" Height="auto" BorderBrush="LimeGreen" BorderThickness="2"
CornerRadius="0,30,0,30">
<Border.Background>
<LinearGradientBrush>
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#e7ebf7" Offset="0.0"></GradientStop>
<GradientStop Color="#cee3ff" Offset="0.5"></GradientStop>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="Title my Window" Padding="5"></TextBlock>
<Grid Grid.Row="1" Background="#B5CBEF">
<TextBlock VerticalAlignment="Center" FontSize="18"
Foreground="White" HorizontalAlignment="Center">My Content</TextBlock>
</Grid>
<TextBlock Text="Footer" Padding="5" Grid.Row="2" HorizontalAlignment="Center"></TextBlock>
</Grid>
</Border>
</Grid>
</Window>
В этом окне содержится элемент Grid с тремя строками, которые используются для строки заголовка, строки нижнего колонтитула и размещаемого между ними содержимого. В строке с содержимым находится еще один элемент Grid, который имеет другой фон и может содержать другие необходимые элементы (в текущий момент в нем находится только один единственный элемент TextBlock).
Для завершения внешнего вида этого окна осталось создать только кнопки, имитирующие размещаемые в правом верхнем углу стандартные кнопки для разворачивания, сворачивания и закрытия окна.

