Last active
January 16, 2022 16:28
-
-
Save JordanMarr/b578a1f389d32c4c5b4c5d83717d1711 to your computer and use it in GitHub Desktop.
Example of Using Elmish.WPF + Rx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window x:Class="ConsoleApp.Wpf.Views.MainWindow" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:local="clr-namespace:ConsoleApp.Wpf.Views" | |
mc:Ignorable="d" | |
Title="MainWindow" Height="450" Width="800"> | |
<Grid Margin="0,25,0,0"> | |
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Top"> | |
<TextBlock Text="{Binding CounterValue, StringFormat='Counter value: {0}'}" Width="110" Margin="0,5,10,5" /> | |
<Button Command="{Binding Decrement}" Content="-" Margin="0,5,10,5" Width="30" /> | |
<Button Command="{Binding Increment}" Content="+" Margin="0,5,10,5" Width="30" /> | |
<TextBlock Text="{Binding StepSize, StringFormat='Step size: {0}'}" Width="70" Margin="0,5,10,5" /> | |
<Slider Value="{Binding StepSize}" TickFrequency="1" Maximum="10" Minimum="1" IsSnapToTickEnabled="True" Width="100" Margin="0,5,10,5" /> | |
<Button Command="{Binding Reset}" Content="Reset" Margin="0,5,10,5" Width="50" /> | |
</StackPanel> | |
</Grid> | |
</Window> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ConsoleApp.Wpf.Program | |
open System | |
open ConsoleApp.Wpf.Views | |
open Elmish | |
open Elmish.WPF | |
open System.Reactive.Subjects | |
open System.Reactive.Linq | |
type Model = | |
{ Count: int | |
StepSize: int | |
StepSizeChanged: Subject<int> } | |
let init () = | |
{ Count = 0 | |
StepSize = 1 | |
StepSizeChanged = new Subject<int>() } | |
type Msg = | |
| Increment | |
| Decrement | |
| SetStepSize of int | |
| Reset | |
| WaitForRx | |
let update msg m = | |
match msg with | |
| Increment -> { m with Count = m.Count + m.StepSize } | |
| Decrement -> { m with Count = m.Count - m.StepSize } | |
| SetStepSize x -> { m with StepSize = x } | |
| Reset -> { init() with StepSizeChanged = m.StepSizeChanged } | |
| WaitForRx -> m | |
let bindings model dispatch = | |
[ | |
"CounterValue" |> Binding.oneWay (fun m -> m.Count) | |
"Increment" |> Binding.cmd (fun m -> Increment) | |
"Decrement" |> Binding.cmd (fun m -> Decrement) | |
"Reset" |> Binding.cmdIf (fun _ -> Reset) (fun m -> m <> init ()) | |
"StepSize" |> Binding.twoWay | |
(fun m -> float m.StepSize) | |
//(fun v m -> int v |> SetStepSize) // Pre-Rx setter -- see below | |
(fun v m -> | |
m.StepSizeChanged.OnNext (int v) | |
WaitForRx | |
) | |
] | |
let rxSubcription initialModel = | |
Cmd.ofSub (fun dispatch -> | |
// Subscribe to observable | |
initialModel.StepSizeChanged | |
.Throttle(TimeSpan.FromMilliseconds(500.0)) | |
.DistinctUntilChanged() | |
.Subscribe(fun size -> | |
dispatch (size |> SetStepSize) | |
) |> ignore | |
initialModel.StepSizeChanged.OnNext(1) // Optional: "Prime the Pump" - set it to the default value of 1 | |
) | |
[<EntryPoint; STAThread>] | |
let main argv = | |
Program.mkSimple init update bindings | |
|> Program.withSubscription rxSubcription | |
|> Program.withConsoleTrace | |
|> Program.runWindowWithConfig | |
{ ElmConfig.Default with LogConsole = true } | |
(MainWindow()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment