[英]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.