Skip to content

Instantly share code, notes, and snippets.

@B-Reif
Created January 8, 2021 00:35
Show Gist options
  • Save B-Reif/215a31a087f490d19ae941e3b88a9dbc to your computer and use it in GitHub Desktop.
Save B-Reif/215a31a087f490d19ae941e3b88a9dbc to your computer and use it in GitHub Desktop.
Program breaks when switching tabs while an item is selected
namespace FuncUITypeRepro
open Avalonia.Controls
open Avalonia.FuncUI.Components
open Avalonia.FuncUI.DSL
open Avalonia.Layout
module Domain =
type RecordA = { Title: string; Pages: int }
type RecordB = { Cost: float; Paid: bool }
type Selection =
| A of RecordA option
| B of RecordB option
type State =
{ AList: RecordA list
BList: RecordB list
Selection: Selection }
type Msg =
| ViewAMsg of RecordA option
| ViewBMsg of RecordB option
let init =
{ AList = [
{ Title = "Book"; Pages = 100 }
{ Title = "Zine"; Pages = 50 }
{ Title = "Brochure"; Pages = 2 }]
BList = [
{ Cost = 1.0; Paid = true }
{ Cost = 100.0; Paid = false }
]
Selection = A None }
let update msg state =
match msg with
| ViewAMsg a -> { state with Selection = A a }
| ViewBMsg b -> { state with Selection = B b }
let aRowView a =
StackPanel.create [
StackPanel.orientation Orientation.Horizontal
StackPanel.children [
TextBlock.create [
TextBlock.text (sprintf "Title: %s" a.Title)
]
TextBlock.create [
TextBlock.text (sprintf "Pages: %i" a.Pages)
]
]
]
let bRowView b =
StackPanel.create [
StackPanel.orientation Orientation.Horizontal
StackPanel.children [
TextBlock.create [
TextBlock.text (sprintf "Cost: %f" b.Cost)
]
TextBlock.create [
TextBlock.text (sprintf "Paid: %b" b.Paid)
]
]
]
let rowsView<'a> (xs: 'a seq) view onChange (selected: 'a option) =
let selectedAttr = selected |> Option.map ListBox.selectedItem |> Option.toList
ListBox.create ([
ListBox.dataItems xs
ListBox.itemTemplate (view |> DataTemplateView<'a>.create)
ListBox.onSelectedItemChanged (tryUnbox<'a option> >> Option.flatten >> onChange)
] @ selectedAttr)
let view state dispatch =
StackPanel.create [
StackPanel.children [
StackPanel.create [
StackPanel.orientation Orientation.Horizontal
StackPanel.children [
Button.create [
Button.content "A list"
Button.onClick (fun _ -> ViewAMsg None |> dispatch)
]
Button.create [
Button.content "B list"
Button.onClick (fun _ -> ViewBMsg None |> dispatch)
]
]
]
(match state.Selection with
| A a -> rowsView state.AList aRowView (ViewAMsg >> dispatch) a
| B b -> rowsView state.BList bRowView (ViewBMsg >> dispatch) b )
]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment