Windows Presentation Foundation (WPF) - это рекомендуемая платформа для пользовательского интерфейса приложений Windows, позволяющая использовать все преимущества современного графического оборудования.
Среди многочисленных возможностей WPF - создание приложений с непрямоугольными окнами. Фигурные окна используются для создания, например: splash-заставок, анимационных картинок или текстовых оповещений поверх всех окон на дисплее. WPF позволяет использовать для создания фигурных окон разнообразную геометрию, полупрозрачные и прозрачные изображения, символы текста визуальных элементов управления.
Статья описывает исходники приложений имеющих сложные фигурные формы окон. Первое приложение использует для формирования контура окна несколько геометрических фигур. Второе приложение динамично изменяет форму окна, создавая анимацию изящного передвижения самой быстрой кошки планеты. Третье приложение не менее интересно - выводит окно в форме текста поверх всех окон Windows. На основе данных исходников возможно написание прикладных программ и игр.
Для создания окон произвольных форм необходимо присвоить некоторым свойствам класса Window определенные значения: установить стиль окна без рамки, разрешить клиентской части становится прозрачной, и конечно же, задний фон окна установить прозрачным.
Суть создания различных форм окон приложений на платформе WPF - сделать само окно прозрачным, но размещаемые на нём элементы оставить видимыми. В результате окно приложения может принимать самые витиеватые формы на основе своих дочерних элементов.
Настройка свойств для прозрачности окна в разметке XAML:
Непрямоугольные окна первого приложения построены на геометрических фигурах базового класса Shape. Окно в форме эллипса плавно перетекает в форму ромба и далее окно становится треугольным.
Классы Ellipse и Polygon в своей классовой иерархии являются еще и наследниками класса FrameworkElement и потому их можно помещать непосредственно в главный контейнер при помощи минимального программного кода.
XAML файл внешнего вида приложения демонстрации фигурных форм окна:
Плавное изменение форм окна реализовано программным способом. Анимация инкремента и декремента прозрачности фигур построена на событиях таймера DispatcherTimer. Плавное исчезание одного элемента происходит синхронно с увеличением видимости другого, обеспечивая динамичную смену форм окна приложения.
Программный код реализации синхронного изменения прозрачности элементов формы окна:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Предварительно скрываем фигуры окна.
MyEllipse.Opacity = 0;
PolyRhombus.Opacity = 0;
PolyTriangle.Opacity = 0;
// Настройка работы таймера анимации.
DispatcherTimer timer = new()
{
Interval = TimeSpan.FromSeconds(0.03)
};
timer.Tick += Timer_Tick;
timer.Start();
}
// Управление изменениями фигуры окна приложения.
double counterOpacity = 1;
int counterElement = 1;
private void Timer_Tick(object? sender, EventArgs e)
{
counterOpacity -= 0.005;
switch (counterElement)
{
case 1:
// Эллипс плавно исчезает
MyEllipse.Opacity = counterOpacity;
// Ромб плавно появляется
PolyRhombus.Opacity = 1 - counterOpacity;
break;
case 2:
// Далее: ромб плавно исчезает
PolyRhombus.Opacity = counterOpacity;
// Плавно появляется треугольник
PolyTriangle.Opacity = 1 - counterOpacity;
break;
case 3:
// Треугольник плавно исчезает
PolyTriangle.Opacity = counterOpacity;
// Эллипс плавно появляется.
MyEllipse.Opacity = 1 - counterOpacity;
break;
}
// Строки обеспечения цикла изменения фигуры окна приложения.
if (counterOpacity <= 0)
{
_ = counterElement == 3 ? counterElement = 1 : counterElement++;
counterOpacity = 1;
}
}
}
Класс Image библиотеки WPF позволяет отображать изображения различных типов: .bmp, .gif, ICO, .jpg, .png, WDP и TIFF. Изображение загружается в элемент управления Image посредством свойства Image.Source. Меняя источники изображений для этого свойства, можно создавать различные формы окна приложения. В следующем примере непрямоугольного окна для создания формы используется последовательность картинок, создающих анимацию бега гепарда. Получается такая вот анимационная форма окна приложения.
Загрузка картинок и анимация созданы полностью программным методом. Файл разметки приложения XAML содержит только минимальный набор кода создания прозрачного окна. В исходном коде файла XAML показанном ниже, содержится только определение свойств окна и главный контейнер, рабочий код поочередного показа картинок находится в программном модуле. Файл XAML определения окна приложения:
Создание анимации серии картинок происходит в цикле. Для возможности циклического наполнения объекта анимации пути к файлам картинок объединены в массив string[]. В качестве объекта анимации используется экземпляр класса ObjectAnimationUsingKeyFrames.
Суть работы анимации. В ObjectAnimationUsingKeyFrames, в качестве ключевых кадров (DiscreteObjectKeyFrame) загружаются источники изображений для элемента управления Image. Для каждого ключевого кадра определяется время, когда его значение (DiscreteObjectKeyFrame.Value) становится выходным объекта анимации. Переключением от кадра к кадру визуально изменяется форма окна приложения. Если в качестве изображений выбрать покадровые картинки, на экране дисплея поверх всех окон создаётся иллюзия движения.
Программный код анимации использует внешние картинки и построен так, что можно легко создавать новые анимации с другим количеством кадров-изображений.
public partial class MainWindow : Window
{
// Количество кадров картинок фигуры окна.
readonly int numberFrames = 0;
// Расположение картинок для обеспечения
// анимационного изменения фигуры окна.
readonly string[] uriSources = {
"anim-1.png",
"anim-2.png", "anim-3.png", "anim-4.png",
"anim-5.png", "anim-6.png"
};
public MainWindow()
{
InitializeComponent();
numberFrames = uriSources.Length;
Animation();
}
private void Animation()
{
ObjectAnimationUsingKeyFrames objectAnimation = new()
{
// Общее время анимации.
Duration = new Duration(TimeSpan.FromSeconds(1.2)),
RepeatBehavior = RepeatBehavior.Forever
};
for (int i = 0; i < numberFrames; i++)
{
// Распределение времени для каждой картинки-кадра.
double quota = (double)i / numberFrames;
objectAnimation.KeyFrames.Add(
new DiscreteObjectKeyFrame()
{
// Установка картинки текущего кадра.
Value = new BitmapImage(new Uri(uriSources[i], UriKind.Relative)),
// Время запуска кадра.
KeyTime = KeyTime.FromPercent(quota)
}
);
}
System.Windows.Controls.Image image = new()
{
Margin = new Thickness(0, 0, 0, 0)
};
// Добавление изображения-контейнера для картинок
// в состав родительской панели.
mainGrid.Children.Add(image);
// Запуск анимации.
image.BeginAnimation(System.Windows.Controls.Image.SourceProperty, objectAnimation);
}
}
На платформе WPF просто создать окно с формой в виде текста. Таким способом можно выводить текстовые надписи поверх всех окон на дисплее.
Третий исходник содержит программный код отображения окна в виде текста для операционной системы Windows. Форму окна определяет элемент вывода надписи Label. Для повышения занимательности текстовой формы окна вывод символов происходит в виде анимации.
Элемент управления Label и его свойства определяются в XAML файле приложения. Управление символами происходит в программном коде класса окна. Ниже показана полная XAML разметка приложения:
Строка текста выводится посимвольно в событии таймера. После вывода полной строки текст исчезает и процесс вывода символов начинается заново. Когда появляется текст его можно захватить курсором мыши и перемещать по экрану монитора. Фон элемента Label определен прозрачным, видимостью обладают только символы.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DispatcherTimer timer = new()
{
Interval = TimeSpan.FromSeconds(0.5)
};
timer.Tick += Timer_Tick;
timer.Start();
}
readonly string hw = "Hello World!";
int counter = 0;
string temp = "";
private void Timer_Tick(object? sender, EventArgs e)
{
// Циклически собираем полный текст по одному символу.
temp += hw[counter];
label1.Content = temp;
counter++;
// Запуск следующей итерации цикла посимвольного вывода текста.
if (counter == hw.Length)
{
counter = 0;
temp = "";
}
}
}
Файл прикрепленного ниже архива содержит три проекта описанных выше приложений. Исходники написаны на языке C# на платформе WPF, в среде программирования MS Visual Studio 2022.