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 I am trying to make a small proof of concept library for reactive UIs and I've encountered this problem when trying to write a function that adds more than a single control to the parent. Standard property setting works when they are singletons, but not when using functions like Observable.range which are iterators.
Is it possible to make this work?
As F# needs some stuff to be added manually to the project file so WPF can be used, here is the repo for this.
Observable.range 0 10toObservable.rangeOn Scheduler.Immediate 0 10. One thing I am having trouble is figuring out where theDispatcherSchedulerdisappeared in .NET Core 3.1. I am not sure what I should substitute it with. I do not necessarily want toScheduler.Immediatefor everything so it would be good to have it.Observable.rangeOn ThreadPoolScheduler.Instance 0 10that gives me theSystem.InvalidOperationExceptionbecause only the UI thread can mutate the UI control.Observable.rangeOn ThreadPoolScheduler.Instance 0 10 |> Observable.observeOn Scheduler.Immediatealso gives me the same exception.