WinForms F# - интерактивное приложение

Все исходники / Язык программирования F# / OS Windows / Desktop / Исходники приложений / WinForms F# - интерактивное приложение
Оглавление:
  1. Windows Forms приложение на языке F#
  2. Перестройка консольного приложения
  3. Структура кода приложения
  4. Модуль инициализации элементов управления
  5. Модуль создания формы приложения
  6. Модуль рабочего кода приложения
  7. Модуль запуска работы приложения
  8. Исходник Windows Forms F#

Windows Forms приложение на языке F#

Приложение Windows Forms на языке программирования F#

Приложение Windows Forms создано на основе консольной F# программы. Код приложения разделён на несколько логических модулей. Модули инициализации элементов управления и формы сгруппированы в отдельной папке. Программный код интерактивности приложения также вынесен в отдельный модуль. Такое построение напоминает разделённый на частичные классы приложение языка C#. В приложение добавлен простейший код F# для демонстрации интерактивности приложения.

На основе предлагаемого приложения можно заниматься изучением языка программирования F#. В оконном приложении гораздо нагляднее смотрятся результаты функций и выражений. Кроме того, на основе данного исходника, можно создавать вполне работоспособные приложения на языке F#.

Перестройка консольного приложения

Изменить файл проекта в Visual Studio

Прежде всего в интегрированной среде программирования MS Visual Studio 2019 создаётся консольное приложение для языка F#. На данный момент для приложения выбрана максимальная целевая платформа .NET5.

Для поддержки функционирования каркаса Windows Forms в файле проекта консольного приложения необходимо сделать соответствующие изменения. В 16 версии Visual Studio нет возможностей визуального добавления поддержки платформы Windows Forms для проектов языка F# (появилась в 17 версии студии), поэтому изменим файл проекта вручную, в встроенном текстовом редакторе. В окне обозревателя решений щелкаем правой кнопкой мыши над именем проекта и в появившемся диалоговом окне вызываем текстовый редактор для файла проекта.

В окне текстового редактора отобразится следующая XML-разметка:
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <WarnOn>3390;$(WarnOn)</WarnOn>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Program.fs" />
  </ItemGroup>

</Project>
Код, заключенный в теге элемента PropertyGroup следует заменить как показано ниже в листинге изменённой XML-разметки файла проекта:
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Program.fs" />
  </ItemGroup>

</Project>

После перезагрузки проекта, в обозревателе решений, в зависимостях проекта, можно увидеть добавленную платформу Microsoft.Windows.Desktop.App.WindowsForms для поддержки оконных элементов.

Обозреватель решений Visual Studio

Структура кода приложения

Структура кода приложения F# Windows Forms

Структура предлагаемого приложения Windows Forms на языке F# состоит из четырех файлов-модулей. Три файла - InitControls.fs, FormModule.fs, CodeFormModule.fs - формируют код формы и находятся в одном пространстве имён. Один - Program.fs - это общий файл запуска приложения. Файлы - InitControls.fs, FormModule.fs - в которых происходит инициализация формы и элементов управления сгруппированы в папку.

Файл формы CodeFormModule.fs, предназначенный для рабочего кодирования, вынесен за пределы папки формы. Такое построение структуры модулей позволило отделить код инициализации формы и визуальных элементов управления от программного кода бизнес-логики приложения.

Модуль в контексте языка программирования F# - это основной способ группирования логически связанного программного кода. Модули могут представлять из себя отдельные файлы или же в одном файле можно объявить несколько модулей. Описываемая структура приложения создавалась именно с целью распределить логически родственные коды F# по отдельным модулям приложения.

Модуль инициализации элементов управления

InitControls.fs - файл-модуль F# объявления и инициализации элементов управления перед добавлением в главную форму приложения. Модуль содержит несколько функций, составные выражения которых возвращают полностью подготовленные элементы для размещения на форме.

Для примера взяты табличный контейнер TableLayoutPanel и четыре кнопки Button, динамически размещаемые в ячейках табличного элемента управления.

Листинг кода модуля InitControls.fs:
namespace MyWindowsForm

open System.Windows.Forms
open System.Drawing

module InitControls = 

// --- Объявление и инициализация свойств элементов управления ---

    // Виды кнопок.
    let standardButton = Size(100, 70)
    let plumpButton = Size(200,200)

    let tableLayoutPanel = 
        let tlp = new TableLayoutPanel()
        tlp.CellBorderStyle <- TableLayoutPanelCellBorderStyle.Single
        tlp.ColumnCount <- 2
        tlp.RowCount <- 2
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)) |> ignore
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)) |> ignore
        tlp.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)) |> ignore
        tlp.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)) |> ignore
        tlp.Dock <- DockStyle.Fill
        tlp.Name <- "tlp"
        tlp

    let button1 = 
        let btn = new Button()
        btn.Name <- "button1"
        btn.Size <- standardButton
        btn.TabIndex <- 0
        btn.Text <- "button1"
        btn.Anchor <- AnchorStyles.None
        btn.BackColor <- Color.BlueViolet
        btn

    let button2 = 
        let btn = new Button()
        btn.Name <- "button2"
        btn.Size <- standardButton
        btn.TabIndex <- 1
        btn.Text <- "button2"
        btn.Anchor <- AnchorStyles.None
        btn.BackColor <- Color.Chartreuse
        btn

    let button3 = 
        let btn = new Button()
        btn.Name <- "button3"
        btn.Size <- standardButton
        btn.TabIndex <- 2
        btn.Text <- "button3"
        btn.Anchor <- AnchorStyles.None
        btn.BackColor <- Color.CadetBlue
        btn

    let button4 = 
        let btn = new Button()
        btn.Name <- "button4"
        btn.Size <- standardButton
        btn.TabIndex <- 3
        btn.Text <- "button4"
        btn.Anchor <- AnchorStyles.None
        btn.BackColor <- Color.BurlyWood
        btn

Модуль создания формы приложения

Модуль FormModule.fs предназначен для объявления собственного класса MyForm формы приложения. В этом же модуле создаётся объект MyForm и к нему добавляются элементы управления предварительно инициированные в модуле InitControls.fs.

Для формирования внешнего вида приложения элементы добавляются к форме внутри поля между спаренными методами SuspendLayout() - ResumeLayout(). Данные методы исключают повторы перерасчета макета формы при добавлении каждого элемента и запускают формирование макета только после вызова метода ResumeLayout(). Конечно, если форма состоит из нескольких элементов, спаренные методы заметно не увеличивают производительность. Но с учётом возможного роста создаваемого проекта приложения, такое построение кода создания формы всё же желательно использовать, тем более что накладные расходы при вызовах SuspendLayout() - ResumeLayout() не существенны.

Программный код модуля формы FormModule.fs:
namespace MyWindowsForm

open System.Windows.Forms
open System.Drawing
open InitControls

module FormModule =

// --- Модуль создания и инициализации формы ---

    type MyForm() =
        inherit Form()
        do
            base.Text <- "Windows Form F#"
            base.StartPosition <- FormStartPosition.CenterScreen
            base.Size <- new Size(800, 600)
            base.TopMost <- true

    // Создаем собственную форму.
    let myForm = new MyForm()

    // Приостановка работы макетов.
    // Приостановка актуальна при большом количестве визуальных элементов.
    // Уменьшает время визуализации формы.
    tableLayoutPanel.SuspendLayout()
    myForm.SuspendLayout()


    // Кнопки добавляются в контейнер TableLayoutPanel.
    tableLayoutPanel.Controls.Add(button1, 0, 0)
    tableLayoutPanel.Controls.Add(button2, 1, 0)
    tableLayoutPanel.Controls.Add(button3, 1, 1)
    tableLayoutPanel.Controls.Add(button4, 0, 1)
    tableLayoutPanel.Controls.Add(button4, 0, 1)

    // Код для исследования работы тандема методов 
    // SuspendLayout() - ResumeLayout()
    // Если раскомментировать данный код и
    // закомментировать вызовы SuspendLayout(), ResumeLayout(),
    // можно заметить задержку показа формы.
    // Если  только раскомментировать этот код 
    // визуализация формы происходит значительно быстрее.
    (* 
    for i = 0 to 2000 do
        let btn = new Button()
        btn.Name <- "button" + (i+10).ToString()
        btn.Size <- new Size(220, 120)
        btn.Text <- "button4"
        btn.Anchor <- AnchorStyles.None
        btn.Dock <- DockStyle.None
        tableLayoutPanel.Controls.Add(btn, 0, 1)
        *)

    // Добавляем таблицу на форму.
    myForm.Controls.Add(tableLayoutPanel)


    // Возобновляем работу макетов.
    tableLayoutPanel.ResumeLayout(false);
    myForm.ResumeLayout(false);

Модуль рабочего кода приложения

Модуль F# CodeFormModule.fs предназначен для рабочего кода приложения, это модуль взаимодействия элементов управления и бизнес-логики приложения. Здесь находятся методы обработки событий компонентов формы, здесь же осуществляется изменение свойств элементов и формы для обеспечения интерактивности программы.

namespace MyWindowsForm

open System
open System.Windows.Forms
open InitControls
open FormModule
open System.Drawing

// --- Модуль рабочего кода формы ---

module Code = 
    
    let myCodeForm = myForm
    myCodeForm.Text <- "Выполнение модуля CodeFormModule"

    button1.Text <- "Первая кнопка"
    button2.Text <- "Вторая кнопка"
    button3.Text <- "Третья кнопка"
    button4.Text <- "Четвертая кнопка"

    // Определение вида кнопки.
    let isStandart (btn: Button) : bool = btn.Size = standardButton
    
    // Обработчик события нажатия для всех кнопок
    let buttons_Click (sender:System.Object) (e:System.EventArgs) : unit = 
        let button: Button = sender :?> Button

        if button = button1 then Console.Beep(300, 300)
        if button = button2 then Console.Beep(500, 300)
        if button = button3 then Console.Beep(1000, 300)
        if button = button4 then Console.Beep(3000, 300)
 
        // Если кнопка стандартная, то делаем её пухлой,
        // и наоборот.
        if isStandart button then
            button.Size <- plumpButton
        else
            button.Size <- standardButton

    // Подключение обработчиков событий 
    button1.Click.AddHandler( new System.EventHandler(buttons_Click) )
    button2.Click.AddHandler( new System.EventHandler(buttons_Click) )
    button3.Click.AddHandler( new System.EventHandler(buttons_Click) )
    button4.Click.AddHandler( new System.EventHandler(buttons_Click) )
    

Модуль запуска работы приложения

В модуле F# Program.fs находится код настроек и запуска приложения.

open System.Windows.Forms
open MyWindowsForm

// Стили элементов управления для поддержки тем операционной системы.
Application.EnableVisualStyles()

// Режим отображения текста в окнах приложения.
// Улучшает качество отображения строк.
// Повышает графическую производительность приложения.
Application.SetCompatibleTextRenderingDefault(false)
    
// Запускает стандартный цикл обработки сообщений приложения 
// в текущем потоке и делает указанную форму видимой.
Application.Run(Code.myCodeForm)

Исходник Windows Forms F#

Исходник написан в интегрированной среде программирования MS Visual Studio 2019, тестировался в Visual Studio 2022 Preview 4.

Скачать исходник

Тема: «WinForms F# - интерактивное приложение» Язык программирования F# WinAppFSharp-vs17.zip Размер:1482 КбайтЗагрузки:131