Skip to content

Commit

Permalink
Merge pull request #599 from marner2/feature/add_oneWaySeqT
Browse files Browse the repository at this point in the history
Add OneWaySeqT
  • Loading branch information
marner2 authored Apr 23, 2024
2 parents ae9a0b0 + 56d69d0 commit fd8a645
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 14 deletions.
16 changes: 16 additions & 0 deletions src/Elmish.WPF/Binding.fs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,22 @@ module Binding =
let id<'a> : string -> Binding<'a, 'a, 'a> =
TwoWay.id
|> createBindingT

/// <summary>
/// The strongly-typed counterpart of <c>Binding.oneWaySeq</c> with parameter <c>getId</c>.
/// Exposes an <c>ObservableCollection</c> of child items for binding.
/// Allows a more efficient update than would be possible without using ids.
/// </summary>
module OneWaySeqT =

/// <summary>
/// Elemental instance of a OneWaySeqT binding
/// </summary>
/// <param name="itemEquals">Defines whether an item is "equal" and needs to be updated if the ids are the same</param>
/// <param name="getId">Unique identifier for each item in the list (for efficient updates).</param>
let id itemEquals (getId: 'a -> 'id) : string -> Binding<_, 'msg, _> =
OneWaySeq.create itemEquals getId
|> createBindingT

/// <summary>
/// Strongly-typed bindings that dispatch messages from the view.
Expand Down
13 changes: 8 additions & 5 deletions src/Samples/SubModelStatic.Core/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ module Counter =

type Model =
{ Count: int
StepSize: int }
StepSize: int
History: (int * int) list }

type Msg =
| Increment
Expand All @@ -21,14 +22,15 @@ module Counter =

let init =
{ Count = 0
StepSize = 1 }
StepSize = 1
History = [] }

let canReset = (<>) init

let update msg m =
match msg with
| Increment -> { m with Count = m.Count + m.StepSize }
| Decrement -> { m with Count = m.Count - m.StepSize }
| Increment -> { m with Count = m.Count + m.StepSize; History = (m.Count, m.History.Length) :: m.History }
| Decrement -> { m with Count = m.Count - m.StepSize; History = (m.Count, m.History.Length) :: m.History }
| SetStepSize x -> { m with StepSize = x }
| Reset -> init

Expand All @@ -41,7 +43,7 @@ type [<AllowNullLiteral>] CounterViewModel (args) =
>> Binding.mapModel (fun (m: Counter.Model) -> m.StepSize)
>> Binding.mapMsg Counter.Msg.SetStepSize

new() = CounterViewModel(Counter.init |> ViewModelArgs.simple)
new() = CounterViewModel({ Counter.init with History = [ (3,1); (0,0) ] } |> ViewModelArgs.simple)

member _.StepSize
with get() = base.Get() stepSizeBinding
Expand All @@ -50,6 +52,7 @@ type [<AllowNullLiteral>] CounterViewModel (args) =
member _.Increment = base.Get() (Binding.CmdT.setAlways Counter.Increment)
member _.Decrement = base.Get() (Binding.CmdT.setAlways Counter.Decrement)
member _.Reset = base.Get() (Binding.CmdT.set Counter.canReset Counter.Reset)
member _.History = base.Get() (Binding.OneWaySeqT.id (=) snd >> Binding.mapModel (fun m -> m.History))


module Clock =
Expand Down
41 changes: 33 additions & 8 deletions src/Samples/SubModelStatic/Counter.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,37 @@
xmlns:vm="clr-namespace:Elmish.WPF.Samples.SubModelStatic;assembly=SubModelStatic.Core"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:CounterViewModel, IsDesignTimeCreatable=True}">
<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>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<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>
<DockPanel Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<TextBlock DockPanel.Dock="Left" Margin="0,5,10,5">History:</TextBlock>
<TextBlock Margin="2,5,2,5">
<Run Text="{Binding CounterValue, Mode=OneWay, StringFormat='({0},'}" />
<Run Text="{Binding History.Count, Mode=OneWay, StringFormat='{}{0})'}" />
</TextBlock>
<ItemsControl ItemsSource="{Binding History}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" TextDecorations="Strikethrough" Margin="2,5,2,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DockPanel>
</Grid>
</UserControl>
2 changes: 1 addition & 1 deletion src/Samples/SubModelStatic/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
xmlns:local="clr-namespace:Elmish.WPF.Samples.SubModelStatic"
xmlns:vm="clr-namespace:Elmish.WPF.Samples.SubModelStatic;assembly=SubModelStatic.Core"
Title="Sub-model"
Height="270"
Height="300"
Width="500"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
Expand Down

0 comments on commit fd8a645

Please sign in to comment.