I apologize upfront for all the code following this question. Its included to answer any questions -- I hope.
In Elmish.WPF, I have submodels of submodels of submodels. Each submodel is esentially a list.
That is, I have a main DataGrid, an "AppointmentTable", bound to a Rows list. Each Row has a column list; Each column has a cell list. Lastly each cell is bound to a name.
Updating each of these models takes more time then I am willing to wait. I have two questions; I a mostly interested in the concepts involved:
- Can each submodel use Cmd.OfAsync.either where only ONE delay is made when ALL the models are updated and screen updated, and
- Would there be any way of running all submodels asynchrounously in parrellel?
TIA
WPF:
<!--DataContext is MainWindow.fs-->
<TabControl ...>
<TabItem Header="Appointments">
<Grid DataContext="{Binding Appointments}">
<local:Appointments Grid.Column="2" Grid.Row="0" />
</Grid>
</TabItem>
<!--DataContext from MainWindow ="{Binding Appointments}"-->
<DataGrid Grid.Row="1" x:Name = "AppointmentTable" ItemsSource="{Binding Rows}" ...>
<DataGrid.Columns>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid DataContext="{Binding Columns[0]}">
<ListView ItemsSource="{Binding InnerRows}"
<ListView.View>
<GridView>
<GridViewColumn Header="First" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=FirstName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Last" Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=LastName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Bd" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=BirthDate}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
----------------------------------------------------------------------------------------------------
F#
module Mainwindow
type Model =
{ Appointments: Appointments.Model
......
}
// DataContext for Appointments.xaml
"Appointments"
|> Binding.SubModel.required Appointments.bindings
|> Binding.mapModel (fun m -> m.Appointments)
|> Binding.mapMsg AppointmentsMsg
module Appointments
type Model =
{ Rows: Row.Model list
}
"Rows" |> Binding.subModelSeq(
(fun m -> m.Rows),
(fun (m, outerRowModel) -> (m.SelectedOuterRow = Some outerRowModel.Id, outerRowModel)),
(fun (_, outerRowModel) -> outerRowModel.Id),
RowMsg,
Row.bindings)
module Row =
type Model =
{ Columns: Column.Model list
...}
"Columns" |> Binding.subModelSeq(
(fun (_, outerRowModel) -> outerRowModel.Columns),
(fun ((b, outerRowModel), columnModel) -> (b && outerRowModel.SelectedColumn = Some columnModel.ColumnId, columnModel)),
(fun (_, columnModel) -> columnModel.ColumnId),
ColumnMsg,
Column.bindings)
module Column =
type Model =
{ Cells: Cell.Model list
....
}
"InnerRows" |> Binding.subModelSeq(
(fun (_, m) -> m.Cells),
(fun ((_, m), cellmodel) -> (m.SelectedCellId = Some cellmodel.Id, cellmodel) ),
(fun (_, cellmodel) -> cellmodel.Id),
snd,
Cell.bindings)
module Cell =
type Model =
{ Id: int
AppointmentTime: DateTime
Appointment: Visit option }
let bindings() = [
"LastName" |> Binding.oneWay(fun (_, c) ->
match c.Appointment with
| Some a -> a.LastName
| None -> ""
)
"FirstName" |> Binding.oneWay(fun (_, c) ->
match c.Appointment with
| Some a -> a.FirstName
| None -> ""
)
"BirthDate" |> Binding.oneWay(fun (_, c) ->
match c.Appointment with
| Some a -> a.BirthDate.ToShortDateString()
| None -> ""
)
"ServiceTime" |> Binding.oneWay(fun (_,c) ->
match c.Appointment with
| Some a -> a.EncounterTime
| None -> None
)
"SelectedLabel" |> Binding.oneWay (fun (b, _) -> if b then " - Selected" else "")
]