Подход к программно строить иерархические компоненты графического интерфейса


На работе я разрабатываю приложения с использованием ручного кодирования качели, и я обнаружил, что у меня есть более легкое время чтения, записи и сохранения иерархических создание компонента с помощью блоков кода:

    JPanel mainPanel = new JPanel(new BorderLayout());
    {
        JLabel centerLabel = new JLabel();
        centerLabel.setText("Hello World");
        mainPanel.add(centerLabel, BorderLayout.CENTER);
    }
    {
        JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0,0));
        {
            JLabel label1 = new JLabel();
            label1.setText("Hello");
            southPanel.add(label1);
        }
        {
            JLabel label2 = new JLabel();
            label2.setText("World");
            southPanel.add(label2);
        }
        mainPanel.add(southPanel, BorderLayout.SOUTH);
    }

Так что я задавался вопросом, как это могло бы выглядеть, используя F# и приложения WinForms, и я перевел этот код например (зайти в "Просмотреть код" на вкладке, затем нажмите на F# -> редактор.в FSX в виде дерева) двумя способами, и я хотел бы обратную связь о том, какие из следующих двух способов лучше. Первый использует код блоков, как подход, показанный в разгаре, и я думаю, это хорошо, но немного суматоху с начала ... конца везде:

open System
open System.Windows.Forms

let form = new Form()
form.Width  <- 400
form.Height <- 300
form.Visible <- true 
form.Text <- "Hello World Form"
begin
    // Menu bar, menus 
    let mMain = new MainMenu()
    begin 
        let mFile = new MenuItem("&File")
        begin                
            let miQuit  = new MenuItem("&Quit")
            miQuit.Click.Add(fun _ -> form.Close())
            mFile.MenuItems.Add(miQuit) |> ignore
        end
        mMain.MenuItems.Add(mFile) |> ignore
    end
    form.Menu <- mMain
end
begin
    // RichTextView 
    let textB = new RichTextBox()
    textB.Dock <- DockStyle.Fill  
    textB.Text <- "Hello World\n\nOK."
    form.Controls.Add(textB)
end

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

open System
open System.Windows.Forms

let form = new Form()
form.Width  <- 400
form.Height <- 300
form.Visible <- true 
form.Text <- "Hello World Form"

form.Menu <-
    // Menu bar, menus 
    let mMain = new MainMenu()
    mMain.MenuItems.Add(
        let mFile = new MenuItem("&File")
        mFile.MenuItems.Add(
            let miQuit  = new MenuItem("&Quit")
            miQuit.Click.Add(fun _ -> form.Close())
            miQuit
        ) |> ignore
        mFile
    ) |> ignore
    mMain

form.Controls.Add(
    // RichTextView 
    let textB = new RichTextBox()
    textB.Dock <- DockStyle.Fill  
    textB.Text <- "Hello World\n\nOK."
    textB
)

Или может кто-то может предложить другой подход к структурированию Ф# + код приложения WinForms, который находится в этом же духе (т. е. подчеркивая иерархию компонентов как визуально, так и в ограничении объема).

Обновление

Я недавно узнала, что в F#, начинают ... конца и ( ... ) являются взаимозаменяемыми. Это означает, что мое беспокойство с первым примером исключается, так как я могу писать:

open System
open System.Windows.Forms

let form = new Form()
form.Width  <- 400
form.Height <- 300
form.Visible <- true 
form.Text <- "Hello World Form"
(
    // Menu bar, menus 
    let mMain = new MainMenu()
    (
        let mFile = new MenuItem("&File")
        (
            let miQuit  = new MenuItem("&Quit")
            miQuit.Click.Add(fun _ -> form.Close())
            mFile.MenuItems.Add(miQuit) |> ignore
        )
        mMain.MenuItems.Add(mFile) |> ignore
    )
    form.Menu <- mMain
)
(
    // RichTextView 
    let textB = new RichTextBox()
    textB.Dock <- DockStyle.Fill  
    textB.Text <- "Hello World\n\nOK."
    form.Controls.Add(textB)
)

И действительно, второй пример может быть записан как

open System
open System.Windows.Forms

let form = new Form()
form.Width  <- 400
form.Height <- 300
form.Visible <- true 
form.Text <- "Hello World Form"

form.Menu <-
    // Menu bar, menus 
    let mMain = new MainMenu()
    mMain.MenuItems.Add begin
        let mFile = new MenuItem("&File")
        mFile.MenuItems.Add begin
            let miQuit  = new MenuItem("&Quit")
            miQuit.Click.Add(fun _ -> form.Close())
            miQuit
         end |> ignore
        mFile
    end |> ignore
    mMain

form.Controls.Add begin
    // RichTextView 
    let textB = new RichTextBox()
    textB.Dock <- DockStyle.Fill  
    textB.Text <- "Hello World\n\nOK."
    textB
end

Такой синтаксис больше не является проблемой, но есть еще разница в стиле.



973
10
задан 11 апреля 2011 в 02:04 Источник Поделиться
Комментарии
1 ответ

Вот мой взгляд на ваш код:

open System
open System.Windows.Forms

let form =
new Form(
Width = 400,
Height = 300,
Visible = true,
Text = "Hello World Form")

// Menu bar, menus
let mMain =
let miQuit = new MenuItem("&Quit")
miQuit.Click.Add(fun _ -> form.Close())

let mFile = new MenuItem("&File")
mFile.MenuItems.Add(miQuit) |> ignore

let mMain = new MainMenu()
mMain.MenuItems.Add(mFile) |> ignore

mMain

form.Menu <- mMain

// RichTextView
let textB = new RichTextBox(Dock = DockStyle.Fill, Text = "Hello World\n\nOK.")

form.Controls.Add(textB)

Я пытался улучшить путем присвоения свойств непосредственно в вызов конструктора. Я также использовал вложенные давайте деклараций для отражения иерархии. Наконец, я использовал отступ вместо явного начала/конца или скобки для разделения блоков.

Также обратите внимание, как я использовал главным в декларации на высшем уровне, главным. Другие могли бы использовать ТМП, я думаю, используя то же имя делает намерения ясными. Это может быть немного запутанным для новичков, хотя.

4
ответ дан 8 июня 2011 в 07:06 Источник Поделиться