I am a newbie to F#. In WPF, I am using DisplayMemberBinding within a Datagrid as:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:AppointmentListView ItemsSource="{Binding Columns[0].AppointmentKeys}" Height="140" Background="Bisque">
<ListView.View>
<GridView>
<GridViewColumn Header="First" DisplayMemberBinding="{Binding FirstName}" Width="100"/>
<GridViewColumn Header="Last" DisplayMemberBinding="{Binding LastName}" Width="120"/>
<GridViewColumn Header="BirthDate" DisplayMemberBinding="{Binding BirthDate, StringFormat=d}" Width="100"/>
</GridView>
</ListView.View>
</local:AppointmentListView>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
The (complete) backing F# module (in Elmish.wpf) is:
module MyDataGrid.DataGrid
open Elmish
open Elmish.WPF
open System
type Visit =
{ ServiceTime: DateTime option
DoNotSee: Boolean option
ChartNumber: int option
LastName: string option
FirstName: string option
Mi: string option
BirthDate: DateTime option
PostingTime: DateTime option
AppointmentTime: DateTime option }
type Cell =
{RowNumber: int
ColumnNumber: int
AppointmentKeys: Visit list
ColumnTime: TimeSpan
AppointmentCount: int
AppointmentTime: DateTime option // all lines in the cell have the same appointment time.
}
let SetCell (rowNumber: int, columnNumber: int) =
let AppointmentsPerCell = 4
{RowNumber = rowNumber
ColumnNumber = columnNumber
AppointmentKeys = [for x in 1 .. AppointmentsPerCell ->
{
ServiceTime = Some System.DateTime.Now
DoNotSee = Some false
ChartNumber = Some 8812
LastName= Some ("LastName" + string x)
FirstName= Some ("FirstName" + string x)
Mi = Some "J"
BirthDate = Some(DateTime(2020,09,14))
PostingTime = Some DateTime.Now
AppointmentTime = Some DateTime.Now
}]
ColumnTime = System.TimeSpan.FromMinutes(float(columnNumber * 15))
AppointmentCount = 4
AppointmentTime = Some(DateTime.Now)
}
type Row =
{RowTime: string
Columns: Cell list}
let SetRow (rowNumber: int, startTime: System.TimeSpan)=
let columnCount = 4
let hr = System.TimeSpan.FromHours(1.0)
let rowTime = startTime + System.TimeSpan.FromTicks(hr.Ticks * int64(rowNumber))
{ RowTime = rowTime.ToString("h':00'")
Columns = [for columnNumber in 1 .. columnCount -> SetCell(rowNumber, columnNumber) ]
}
type Model =
{ AppointmentDate: DateTime
Rows: Row list
SelectedRow: Row option}
type Msg =
| SetAppointmentDate of DateTime
| SetSelectedRow of Row option
let init =
let rowCount = 9
let startTime = TimeSpan.FromHours(float(8))
{ AppointmentDate = DateTime.Now
Rows = [for rowNumber in 0 .. rowCount -> SetRow(rowNumber, startTime)]
SelectedRow = None
}
let update msg m =
match msg with
| SetAppointmentDate d -> {m with AppointmentDate = d}
| SetSelectedRow r -> {m with SelectedRow = r}
let bindings () : Binding<Model, Msg> list = [
"SelectedAppointmentDate" |> Binding.twoWay( (fun m -> m.AppointmentDate), SetAppointmentDate)
"Rows" |> Binding.oneWay( fun m -> m.Rows)
"SelectedRow" |> Binding.twoWay( (fun m -> m.SelectedRow), SetSelectedRow)
]
let designVm = ViewModel.designInstance init (bindings ())
let main window =
Program.mkSimpleWpf (fun () -> init) update bindings
|> Program.withConsoleTrace
|> Program.runWindowWithConfig
{ ElmConfig.Default with LogConsole = true; Measure = true }
window
The DisplayMememberBindings show LastName as "Some(LastName1)" and BirthDate as "Some(09/14/2020 00:00:00)".
How can I get the LastName: string option to return either null or the value of the string so the display shows "LastName1" and not "Some(LastName1)?
The same goes for the birth date, how to show BirthDate as "9/14/2020" and not "Some(09/14/2020 00:00:00)?
TIA
Full source code at: Example DataGrid
Your code only has three bindings. You should have a binding for every individual piece of data. Specifically, you should change your
Rows
binding from aOneWay
binding to aSubModel
binding. Then repeat this for all your other types.Then, the question you specifically asked about is how to display
LastName1
instead ofSome(LastName1)
and9/14/2020
instead ofSome(09/14/2020 00:00:00)
. Create the bindings for these individual pieces of optional data withBinding
methods that ends inOpt
likeBinding.oneWayOpt
orBinding.twoWayOpt
.