使用 Elmish.wpf/F#,如何在 WPF 中将字符串选项显示为字符串或空值,而不是 "Some(string)"?
With Elmish.wpf/F#, how to display in WPF a string option as the string or null, not "Some(string)"?
我是 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 将 LastName 显示为“Some(LastName1)”,将 BirthDate 显示为“Some(09/14/2020 00:00:00)”。
如何让 return 的 LastName: string 选项为 null 或字符串的值,以便显示显示“LastName1”而不是“Some(LastName1)”?
出生日期也一样,如何将出生日期显示为“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)
。使用以 Opt
结尾的 Binding
方法为这些单独的可选数据片段创建绑定,例如 Binding.oneWayOpt
or Binding.twoWayOpt
.
对于像我这样的新手,这里是 my 完整的 F# working Elmish 解决方案。WPF/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
我是 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 将 LastName 显示为“Some(LastName1)”,将 BirthDate 显示为“Some(09/14/2020 00:00:00)”。
如何让 return 的 LastName: string 选项为 null 或字符串的值,以便显示显示“LastName1”而不是“Some(LastName1)”?
出生日期也一样,如何将出生日期显示为“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)
。使用以 Opt
结尾的 Binding
方法为这些单独的可选数据片段创建绑定,例如 Binding.oneWayOpt
or Binding.twoWayOpt
.
对于像我这样的新手,这里是 my 完整的 F# working Elmish 解决方案。WPF/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