【发布时间】:2020-07-20 16:02:39
【问题描述】:
module StackTenButtons.Try2
open System
open System.Windows
open System.Windows.Controls
open System.Reactive.Linq
open System.Reactive.Disposables
open FSharp.Control.Reactive
let control c l =
Observable.Create (fun (sub : IObserver<_>) ->
let c = c()
let d = new CompositeDisposable()
List.iter (fun x -> d.Add(x c)) l
sub.OnNext(c)
d :> IDisposable
)
let do' f c = f c; Disposable.Empty
let prop s v c = Observable.subscribe (s c) v
let w =
control Window [
prop (fun t v -> t.Content <- v) <| control StackPanel [
do' (fun pan ->
Observable.range 0 10
|> Observable.subscribe (fun x -> pan.Children.Add(Button(Content=sprintf "Button %i" x)) |> ignore)
|> ignore
)
]
]
[<STAThread>]
[<EntryPoint>]
let main _ = w.Subscribe (Application().Run >> ignore); 0
我正在尝试为反应式 UI 制作一个小型概念证明库,并且在尝试编写向父级添加多个控件的函数时遇到了这个问题。标准属性设置在它们是单例时有效,但在使用像 Observable.range 这样的迭代器时无效。
是否有可能做到这一点?
由于 F# 需要手动将一些东西添加到项目文件中,以便可以使用 WPF,here is 的 repo。
【问题讨论】:
-
当我将
Observable.range 0 10更改为Observable.rangeOn Scheduler.Immediate 0 10时它可以工作。我遇到的一件事是找出DispatcherScheduler在.NET Core 3.1 中消失的位置。我不确定我应该用什么代替它。我不一定想要Scheduler.Immediate来处理所有事情,所以拥有它会很好。 -
与其创建控件,不如假设我从某处异步获取资源。我如何在 UI 线程上观察它?
-
如果我这样做
Observable.rangeOn ThreadPoolScheduler.Instance 0 10给我System.InvalidOperationException因为只有 UI 线程可以改变 UI 控件。Observable.rangeOn ThreadPoolScheduler.Instance 0 10 |> Observable.observeOn Scheduler.Immediate也给了我同样的例外。
标签: wpf f# system.reactive