问题描述
我是F#的新手。在WPF中,我在Datagrid中使用displayMemberBinding作为:
<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>
(完整的)支持F#模块(在Elmish.wpf中)是:
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
displayMememberBindings将姓氏显示为“ Some(LastName1)”,将BirthDate显示为“ Some(09/14/2020 00:00:00)”。
如何获取LastName:string选项以返回null或字符串值,以便显示屏显示“ LastName1”而不是“ Some(LastName1)?”
出生日期也是如此,如何将BirthDate显示为“ 9/14/2020”而不是“ Some(09/14/2020 00:00:00)”?
TIA
完整源代码位于:Example DataGrid
解决方法
您的代码只有三个绑定。您应该为每个单独的数据都绑定一个绑定。具体来说,您应该将Rows
绑定从OneWay
绑定更改为SubModel
绑定。然后对所有其他类型重复此操作。
然后,您专门询问的问题是如何显示LastName1
而不是Some(LastName1)
和9/14/2020
而不是Some(09/14/2020 00:00:00)
。使用Binding
结尾的Opt
方法为这些单独的可选数据片段创建绑定,例如Binding.oneWayOpt
或Binding.twoWayOpt
。
对于像我这样的新手,这是Elmish.WPF / F#中的我完整的F#工作解决方案:
module MyDataGrid.DataGrid
open Elmish
open Elmish.WPF
open System
module Visit =
type Model =
{ 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
Id: int}
let SetVisits appointmentsPerCell = [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
Id = x
}]
let bindings() = [
"FirstName" |> Binding.oneWayOpt( fun (_,m) -> m.FirstName)
"LastName" |> Binding.oneWayOpt( fun (_,m) -> m.LastName)
"BirthDate" |> Binding.oneWayOpt( fun (_,m) -> m.BirthDate)
"ServiceTime" |> Binding.oneWayOpt( fun (_,m) -> m.ServiceTime)
]
module Cell =
type Model =
{ RowNumber: int
ColumnNumber: int
AppointmentKeys: Visit.Model list
ColumnTime: TimeSpan
AppointmentCount: int
AppointmentTime: DateTime option // all lines in the cell have the same appointment time.
Id: int
}
let SetCell (rowNumber: int,columnNumber: int) =
let AppointmentsPerCell = 4
{RowNumber = rowNumber
ColumnNumber = columnNumber
AppointmentKeys = Visit.SetVisits AppointmentsPerCell
ColumnTime = System.TimeSpan.FromMinutes(float(columnNumber * 15))
AppointmentCount = 4
AppointmentTime = Some(DateTime.Now)
Id=rowNumber*10 + columnNumber
}
let bindings() =[
"AppointmentKeys" |> Binding.subModelSeq(
(fun (_,m) -> m.AppointmentKeys),(fun v -> v.Id),Visit.bindings
)
]
module Row =
type Model =
{ RowTime: string
Columns: Cell.Model list
Id: int }
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 -> Cell.SetCell(rowNumber,columnNumber) ]
Id = rowNumber
}
let bindings () = [
"RowTime" |> Binding.oneWay( fun (_,r) -> r.RowTime)
"Columns" |> Binding.subModelSeq(
(fun (_,m) -> m.Columns),(fun c -> c.Id),Cell.bindings
)
]
type Model =
{ AppointmentDate: DateTime
Rows: Row.Model list
SelectedRow: Row.Model option}
type Msg =
| SetAppointmentDate of DateTime
| SetSelectedRow of Row.Model option
let init () =
let rowCount = 9
let startTime = TimeSpan.FromHours(float(8))
{ AppointmentDate = DateTime.Now
Rows = [for rowNumber in 0 .. rowCount -> Row.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.subModelSeq(
(fun m -> m.Rows),(fun r -> r.Id),Row.bindings
)
"SelectedRow" |> Binding.twoWay( (fun m -> m.SelectedRow),SetSelectedRow)
]
let main window =
Program.mkSimpleWpf init update bindings
|> Program.withConsoleTrace
|> Program.runWindowWithConfig
{ ElmConfig.Default with LogConsole = true; Measure = true }
window
enter code here