Skip to content

Instantly share code, notes, and snippets.

@JordanMarr
Created January 18, 2019 20:37
Show Gist options
  • Save JordanMarr/42297f872e470de4544e71de0c4164df to your computer and use it in GitHub Desktop.
Save JordanMarr/42297f872e470de4544e71de0c4164df to your computer and use it in GitHub Desktop.
module ConsoleApp.Wpf.Program
open System
open Elmish
open Elmish.WPF
open FSharp.Control.Reactive
type Model =
{ Contacts: Rolodex.Contact seq
ContactsFilter: string
ContactsFilterChanged: System.Reactive.Subjects.Subject<string> }
type Msg =
| SetContactsFilter of string
| WaitForRx
/// Wraps the Rolodex MVU bits in a class with an injectable facade.
type RolodexMVU(facade: Rolodex.Facade) =
let contacts = facade.GetContacts()
let init () =
{ Contacts = []
ContactsFilter = ""
ContactsFilterChanged = Subject<string>.broadcast }
let update msg m =
match msg with
| SetContactsFilter filterText ->
{ m with Contacts = contacts |> Seq.filter (fun c -> c.Name.ToLower().Contains(filterText.ToLower())) }
| WaitForRx -> m
let bindings model dispatch =
[
"Contacts" |> Binding.oneWay (fun m -> m.Contacts)
"ContactsFilter" |> Binding.twoWay
(fun m -> m.ContactsFilter)
(fun v m ->
m.ContactsFilterChanged.OnNext(v)
WaitForRx
)
]
let rxSubcription model =
Cmd.ofSub (fun dispatch ->
// Subscribe to observable
model.ContactsFilterChanged
|> Observable.throttle (TimeSpan.FromMilliseconds(500.0))
|> Observable.distinctUntilChanged
|> Observable.subscribe (fun filterText ->
filterText |> SetContactsFilter |> dispatch
)
|> ignore
model.ContactsFilterChanged
|> Subject.onNext "" // "Prime the Pump"
|> ignore
)
member this.ShowView() =
Program.mkSimple init update bindings
|> Program.withSubscription rxSubcription
|> Program.withConsoleTrace
|> Program.runWindowWithConfig
{ ElmConfig.Default with LogConsole = true }
(Views.RolodexView())
[<EntryPoint; STAThread>]
let main argv =
let mvu = new RolodexMVU(new Rolodex.Facade())
mvu.ShowView()
<Window x:Class="ConsoleApp.Wpf.Views.RolodexView"
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="Contacts" Height="450" Width="400">
<DockPanel LastChildFill="True" Margin="5" >
<Grid DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label>Filter:</Label>
<TextBox Grid.Column="1" Text="{Binding ContactsFilter, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="Auto"></TextBox>
</Grid>
<ListBox DockPanel.Dock="Bottom" ItemsSource="{Binding Contacts}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Window>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment