Здравствуйте, уважаемые читатели моего блога. Сегодня мы поговорим о взаимодействии F#-приложения с Windows Forms и WPF. В последнее время я активно занимаюсь изучением F# и предлагаю вам окунуться вместе со мной в возможности
этого языка. Как говорится, меньше слов – больше дела. Для
начала создадим проект с названием TestFSharp для примера. Как
это сделать, можно увидеть на рисунке ниже.
Затем нужно удалить точку входа в нашу программу, которая по умолчанию будет у
Вас создана.
[<EntryPoint>]
let main
argv =
printfn "%A" argv
0 // return an integer exit code
Эта
точка входа обозначает, что Ваше приложение будет запущено на Console Application. Нам же нужно будет запустить наше приложение как
приложение Windows Application. Для этого переходим в окно настроек нашего проекта и
изменяем запускаемый проект с на Console Application на Windows Application, как показано на рисунке ниже.
А
сейчас немножко "поколдуем" над нашим кодом. Для того, чтобы наши контролы
заработали, нужно добавить ссылки на System.Windows.Forms и
System.Drawing.
После
того, как мы всё сделали, можно спокойно перейти к реализации. В первую очередь необходимо указать пространства имен, которые мы будем использовать. Для
этого добавим в наш проект таки строки:
open System
open
System.Windows.Forms
open System.Drawing
Мы говорим нашей исполняющей среде, что будем использовать контролы и
классы с данного пространства имен. Давайте для примера создадим простенькую форму,
в которую добавим кнопочку, при нажатии на которую выведем сообщение через MessageBox.Show(). Полный
исходный код приведен ниже.
open System
open
System.Windows.Forms
open
System.Drawing
let form = new
Form(Text = "F# Program")
let button
= new Button(Text = "Button
Click")
button.Location <- new Point(
100, 100)
form.Controls.Add(button)
button.Click.Add(fun evArgs -> MessageBox.Show("Click me") |> ignore)
Application.Run(form)
С помощью строк
let form = new
Form(Text = "F# Program")
let button
= new Button(Text = "Button
Click")
создаем форму, затем создаем кнопку и добавляем ее на форму. Затем чтобы наш контрол не выводился с верхнего левого края, зададим
ему отступ справа и слева на 100 пикселей.
button.Location <- new Point( 100, 100)
Это делается с помощью оператора <-. Этот оператор позволяет изменять
только свойства, помеченные как mutable. По умолчанию свойства в F# помечены как неизменяемые, поэтому помните, когда
будете писать код, что для свойств нужно указывать явно, что они являются
изменяемыми. Строка
form.Controls.Add(button)
добавляет
созданную кнопку на форму.
button.Click.Add(fun evArgs -> MessageBox.Show("Click me") |> ignore)
Код,
приведенный выше, создает обработчик события нажатия на кнопку. Этот обработчик
создан с помощью лямбда-выражения
fun evArgs -> MessageBox.Show("Click me")
Поскольку
нам не важен результат, который возвращает метод MessageBox.Show, мы указываем игнорировать данный результат с помощью
строки
|> ignore
После нажатия на клавишу F5 видим результат, подобный рисунку
ниже.
F# и WPF
Приведем
еще один пример использования F# совместно с WPF. Поскольку пример с созданием контролов мы уже видели в предыдущем примере, рассмотрим вариант с использованием XAML-файла. Вы не
сможете создать XAML-файл в самой среде Visual Studio 2012, поскольку эти типы файлов недоступны для проекта на
языке F#.
Нам
необходимо предпринять маленькую хитрость и создать XAML-окно в отдельном
редакторе, например, в той же студии или в Expression Blend, а затем добавить его в наш проект. Признаюсь, что для
реального проекта это не очень удобно. Но у нас тестовый пример, и сведения о том, как запустить WPF-приложение с F#, думаю, будут интересными. Для работы с нашим WPF-приложением необходимо добавить следующие библиотеки в проект:
WindowsBase.dll
PresentationCore.dll
PresentationFramework.dll
System.Xaml.dll
Пример показан на рисунке ниже.
Простой
пример без использования XAML-файла можно
написать так:
open System
open
System.Windows
let win = new
Window(Title = "Hello WPF")
win.Show() |> ignore
#if
COMPILED
[<STAThread()>]
do
let app
= new
Application()
app.Run() |>
ignore
#endif
Но
похожий пример мы уже создавали, когда написали Windows Forms-приложение в начале статьи. Поэтому пойдем более
сложным путем. Выберем созданный уже заранее приготовленный шаблон и добавим
его в студию, нажав на проекте правой клавишей мыши и выбрав пункт меню Add->Existing
Item…
Выбираем
All Files (*.*) и добавляем наше окно, которое хотим отобразить
на экране.
Вот
какой вид имеет наше окно:
<Window x:Class="WpfApplicationTestFSharpProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Orientation="Vertical">
<TextBox x:Name="FSharpBook" Text="Test"></TextBox>
<Button x:Name="PressButton" Content="Click
Me"></Button>
</StackPanel>
</Grid>
</Window>
Нам
необходимо для прикрепленного
окна MainWindow.xaml установить в окне
Properties свойство
Build Action в
Resources. После
того, как мы проделали необходимую работу, посмотрим, как будет выглядеть
наше решение.
open System
open
System.Windows
open
System.Windows.Controls
[<STAThread>]
[<EntryPoint>]
let main(_)
=
let window
= Application.LoadComponent(new Uri("MainWindow.xaml", UriKind.Relative)) :?> Window
let button
= window.FindName("PressButton") :?> Button
let textBox
= window.FindName("FSharpBook") :?> TextBox
textBox.Text <-
"Hello F#"
button.Click.Add(fun _ ->
textBox.Text
<- textBox.Text.ToUpper())
window.Show()
|> ignore
let
application = new Application()
application.Run()
Для нашей программы укажем точку входа и то, что наша программа
должна запускаться в основном потоке. Это делается с помощью строк
[<STAThread>]
[<EntryPoint>]
let main(_) =
Строка _ как параметр функции main указывает на то, что нам не важно, какие параметры будут переданы в функцию,
так как функция принимает параметры командной строки, мы можем указать args как аргумент функции. Следующим шагом мы
загружаем наше окно с помощью функции
let window
= Application.LoadComponent(new Uri("MainWindow.xaml",
UriKind.Relative))
и приводим результат, который возвращает нашу функцию к типу Window (Примечание: функция Application.LoadComponent возвращает
Object). Операция приведения в F# очень простая и легко
запоминается:
:?>
Следующим этапом находим наши контролы: TextBox и Button по имени.
let button
= window.FindName("PressButton") :?> Button
let textBox
= window.FindName("FSharpBook") :?> TextBox
Для
примера изменим текст, который был в TextBox, и напишем новый
текст "Hello F#". Как это сделать, посмотрите ниже:
textBox.Text <- "Hello F#"
Для кнопки мы создадим обработчик события с помощью
лямбда-выражения по такому же принципу, как делали для примера Windows Forms. Только для данного примера мы в обработчике изменим текст в TextBox, который нашли выше, на текст верхнего регистра.
button.Click.Add(fun _ ->
textBox.Text
<- textBox.Text.ToUpper())
Осталось каких-то "два штриха". Нужно показать наше созданное окно
и запустить основное приложение с помощью метода application.Run()
Итоги
В данной статье мы рассмотрели возможности взаимодействия F#-проекта с Windows Forms и WPF-контролами. Надеюсь, Вам понравился экскурс в мир F#. Жду ваши комментарии и с удовольствием на них отвечу.
No comments:
Post a Comment