繁体   English   中英

F# 中的 GUI 更新模式

[英]GUI update patterns in F#

我正在寻找将 model 更新传播到 GUI 的最佳方式,使用“经典”(如:非反应性功能)GUI 工具包: Terminal.GUI 目前我有这个代码(简化):

    type Tui(state: StateManager) =
        let state = state

        let window = Window(bla bla bla)

        let lblPath = Label(bla bla bla)

        let lstView =
            { new ListView(bla bla bla) with
                  member this.ProcessKey(k: KeyEvent) =

                      let updateViews() =
                          Application.MainLoop.Invoke(fun () ->
                            this.SetSource model.CurrentState.LstData
                            lblPath.Text <- ustr model.CurrentState.CurrPath)

                      match k.Key with
                      | Key.CursorRight -> 
                            state.changeTheState()
                            updateViews()
                            true
                      | _ -> true }
        do
            Application.Init()
            // add all GUI components: window.add(lblPath), etc
            Application.Run()
            // XXX repetition of updateViews() above!
            Application.MainLoop.Invoke(fun () ->
                lstView.SetSource model.CurrentState.LstData
                lblPath.Text <- ustr model.CurrentState.CurrPath)

这里的问题是更新视图组件的代码是重复的。 我相信这是因为:

  • ListView object 表达式的ProcessKey方法中,我无法访问 Tui class 的任何外部方法(这可能也是因为 F# 编译器仅是一次性(?))
  • 在该方法之外,我无法访问updateView function

有没有更好的方法来避免代码重复? 我是否使用了错误的模式 GUI 更新模式?

(完整代码在这里

当然,它不需要太复杂 - 重构你的更新只接受一个 listview 参数:

let updateViews (lstView: ListView) =
      Application.MainLoop.Invoke(fun () ->
          lstView.SetSource state.CurrentState.LstData
          ...
      )

在成员定义中,调用:

updateViews(this)

在下面,您可以使用updateViews lstView

当您使用 object 表达式时,表达式的类型将变为您在new <type>中指定的类型,因此您在内部进行的任何类型扩充都不会在外部出现。 对于更多的 OOP 方法,声明一个中间类型:

[<AbstractClass>] 
type UpdateableList() = 
    inherit ListView([||]) 
    abstract member Update: unit -> unit

实现你的更新逻辑:

  { new UpdateableList(X = Pos.At(0), Y = Pos.At(2), ...) with
            member this.Update() =
                ...

在您的设置中,您可以访问公共方法:

lstView.Update()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM