А АFriday 2 September 2022

GUI с помощью Windows Presentation Foundation.

Всем привет.

Рациональным подходом к созданию GUI в Powershell будет случай когда декларативное описание графического интерфейса отделяется от остального кода исполнения. Такой подход обеспечивает технология Windows Presentation Foundation (WPF).

При использовании WPF графический интерфейс описывается с помощью бази­рующегося на XML языка разметки XAML (Extensible Application Markup Lan­guage). Таким образом, дизайн интерфейса отделяется от логики сценария, рабо­тающего с этим интерфейсом. Для работы с объектами WPF в PowerShell нужно загрузить сборку PresentationFramework:

PS C: \Users\xenial> Add-Type -AssemblyName PresentationFramework

Создадим сначала простейшее диалоговое окно без элементов размером 300x200 пик­селов и с заголовком "Форма WPF". На первом шаге с помощью here-string созда­дим строку $xaml с XML-разметкой, содержащей один тег <window/> с атрибутами Width, Height и Title, и преобразуем эту строку в объект XML:

PS С:\Users\xenial> [xml]$xaml = @"

<Window

xmlns="http: //schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns :x="http: //schemas.microsoft.com/winfx/2006/xaml"

        x:Name="Window" Тitle="Form WPF” Height=”200" Width=”300”

 />

"@


Атрибут xmlns здесь определяет пространство имен, содержащее имена элементов и атрибутов, которые можно использовать в разметке Windows Presentation Foundation. Префикс х перед атрибутом указывает на то, что данный атрибут отно­сится к данному пространству имен. Создадим теперь экземпляр класса XmlNodeReader, передав ему объект $xami в каче­стве аргумента. Полученный объект сохраним в переменной $ reader:

PS С:\Users\xenial> $reader = (New-Object System.Xml.XmlNodeReader $xaml)

Объект, соответствующий диалоговому окну, создается с помощью статического метода Load () класса XamlReader. В этот метод передается объект $ reader:

PS С:\Usегs\ xenial> $window = [Windows.Markup.XamlReader] : : Load($reader)

Теперь окно можно отобразить на экране с помощью метода showDiaiog:

PS С:\Users\xenial> $window.ShowDialog()


При этом работа оболочки PowerShell приостановится, для ввода следующей команды нужно закрыть наше диалоговое окно. Добавим в нашу форму элемент <Grid>, задающий сетку для размещения других элементов управления.

PS С:\Users\xenial> [xml]$xaml = @"

 <Window

xmlns="http: //schemas .micro soft. ccm/winfx/2006/xaml/presentation"

xmlns: x="http: //schemas.microsoft. com/winfx/2006/xaml"

x :Name=" Window" Title="Form WPF" Height="200" Width="300"

<Grid x:Name="Grid">

<Gr id.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="Auto"/>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="Auto"/>

<ColumnDefinition Width="Auto"/>

</Grid.ColumnDefinitions>

</Grid>

 </Window>

 "@


Сетка не отображается на экране, поэтому внешний вид главной формы (диалого­вого окна) не изменится, форма останется пустой. Поместим теперь на форму надпись (тег <Label> С именем Message) и кнопку (тег <Button> с именем changeMessage). Надписи в этих элементах задаются с помощью атрибута content, расположение элемента в ячейке сетки определяется с помощью атрибутов Grid.Column И Grid.Row.

PS C: \Users\xenial> [xml]$xaml = @"

 <Window

xmlns="http: //schemas .microsoft. com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas .microsoft .com/ winf x/2006/xaml"

x:Name="Window” Title="Form WPF" Height=”200” Width="300”

 >

<Grid x:Name="Grid">

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="Auto"/>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="Auto"/>

<ColumnDefinition Width="Auto"/>

</Grid.ColumnDefinitions>

<Label x:Name= "Message"

Content="Hello!"

Grid.Column=”0"

Grid.Row="0"

/>

<Button x:Name= " ChangeMessage"

Content="Press!"

Grid.Column="1"

Grid.Row="1"

/>

</Grid>

 </Window>

 "@


Отобразим форму:

С: \Users\xenial> $reader = (New-Object System.Xml. XmlNodeReader $xaml)

PS C:\Users\xenial> $window = [Windows.Markup.XamlReader] ::Load($reader)

PS C:\Users\xenial> $window.ShowDiaiog()


С помощью команды Set-Content поместим XAML-разметку для нашей формы в файл wpf test.xaml, в коде выше добавим в конец строку:

...

 "@ | Set-Content -Path ./mywpf.xaml -Encoding UTF8


Теперь для отображения формы мы можем прочитать ее разметку из файла:

PS С:\Users\xenial> [xml]$xaml = Get-Content -Path ./mywpf.xaml -Encoding UTF8

PS C:\Users\xenial> $reader = (New-Object System.Xml.XmlNodeReader $xaml)

PS C:\Users\xenial> $window = [Windows.Markup.XamlReader] ::Load($reader)


Осталось добавить форме функциональность, создав обработчики нужных собы­тий, возникающих на элементах управления. Это делается практически так же, как и при использовании WinForms, за исключением того, что нам нужно предвари­тельно создать объекты-переменные, соответствующие элементам управления за­груженной формы.

Напомним, что для тегов элементов управления мы задавали атрибут Name из про­странства имен XAML-разметки для WPF:

<Label x:Name="Message"

...

/>

<Button х:Name="ChangeMessage"

...

/>

По значению атрибута Name с помощью метода $ window. FindName о получим ссылки на соответствующие элементы управления:

PS С: \Users\xenial> $messageLabel = $ window. FindName ("Mеssage")

PS C: \Users\xenial> $changeButton = $ window. FindName ("ChangeMessage”)


Пусть, как и в примере с WinForms, при нажатии кнопки текст надписи в нашей форме должен измениться на ’’Buy-buy?”. Для этого зададим обработчик события Click на кнопке с помощью метода Add_click:

PS C:\Users\xenial> $changeButton. Add_Click ({$messageLabel. Content= ’ Buy-buy? ’ })


Теперь форму можно отобразить на экране и проверить результат нажатия кнопки

PS С:\Users\xenial> $window.ShowDialog()

Таким образом, при работе с WPF мы можем создавать и изменять дизайн интер­фейса независимо от его функционала. Кроме того, XAML-описание формы не зависит от специфики PowerShell, как это было в случае интерфейса на базе WinForms, поэтому вариантов выбора визуально­го конструктора для построения форм становится больше. Кроме платных специализированных сред разработки сценариев PowerShell (Sapien PowerShell Studio, PowerShell GUI Designer) можно воспользоваться бесплатной платформой Microsoft Visual Studio Community Edition. Также у вас есть шанс что в этом случае ваше GUI-приложение будет работать на серверах Windows Core с включенным минимальным графическим интерфейсом.

Удачи.

Слава Украине!


No comments:

Post a Comment

А что вы думаете по этому поводу?

Версия на печать

Популярное