WPF Collections tutorial
The resulting app will contain a listbox, an 'Add Item' button, and label displaying the current selection and will delete the selected item when pressing the Delete key.
First, a small helper used for the ListBox.SelectedItem:
1: 2: 3: 4: |
|
The app event type - adding, removing and selecting an item
1:
|
|
ItemModel itself is defined here, containing a string property. As it won't change, this is a plain property, not a ReactiveProperty
We also override ToString() to avoid defining a template for the sake of the tutorial.
1: 2: 3: |
|
The concrete WPF window type - this should be replaced by a .xaml loaded by FsXaml in the real world.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: |
|
Item Qualia view: no template here, just a Label. That's why we overrode ToString(). In SetBindings, we just set once the label content - this is equivalent to a binding mode Once.
1: 2: 3: 4: |
|
List model : the items collection and a reactive property containing the selected item. As it can be null, this is an ItemModel option.
1: 2: 3: |
|
The view inherits DerivedCollectionSourceView, but this is a convenience class providing one helper method at the moment, linkCollection. You could just do the plumbing by hand.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: |
|
Typical dispatcher -
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: |
|
1: 2: 3: 4: 5: 6: 7: 8: |
|
Full name: Tutorial.wpf.cast
Full name: Microsoft.FSharp.Core.obj
Full name: Microsoft.FSharp.Core.option<_>
| Add
| Remove
| SelectionChanged of ItemModel option
Full name: Tutorial.wpf.Events
type ItemModel =
new : s:string -> ItemModel
override ToString : unit -> string
member Text : string
Full name: Tutorial.wpf.ItemModel
--------------------
new : s:string -> ItemModel
Full name: Tutorial.wpf.ItemModel.ToString
type ListViewWindow =
inherit Window
new : unit -> ListViewWindow
member Button : Button
member Label : Label
member List : ListBox
Full name: Tutorial.wpf.ListViewWindow
--------------------
new : unit -> ListViewWindow
type Window =
inherit ContentControl
new : unit -> Window
member Activate : unit -> bool
member AllowsTransparency : bool with get, set
member Close : unit -> unit
member DialogResult : Nullable<bool> with get, set
member DragMove : unit -> unit
member Hide : unit -> unit
member Icon : ImageSource with get, set
member IsActive : bool
member Left : float with get, set
...
Full name: System.Windows.Window
--------------------
Window() : unit
type Label =
inherit ContentControl
new : unit -> Label
member Target : UIElement with get, set
static val TargetProperty : DependencyProperty
Full name: System.Windows.Controls.Label
--------------------
Label() : unit
type Button =
inherit ButtonBase
new : unit -> Button
member IsCancel : bool with get, set
member IsDefault : bool with get, set
member IsDefaulted : bool
static val IsDefaultProperty : DependencyProperty
static val IsCancelProperty : DependencyProperty
static val IsDefaultedProperty : DependencyProperty
Full name: System.Windows.Controls.Button
--------------------
Button() : unit
val list : ListBox
--------------------
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
type ListBox =
inherit Selector
new : unit -> ListBox
member ScrollIntoView : item:obj -> unit
member SelectAll : unit -> unit
member SelectedItems : IList
member SelectionMode : SelectionMode with get, set
member UnselectAll : unit -> unit
static val SelectionModeProperty : DependencyProperty
static val SelectedItemsProperty : DependencyProperty
Full name: System.Windows.Controls.ListBox
--------------------
ListBox() : unit
type StackPanel =
inherit Panel
new : unit -> StackPanel
member CanHorizontallyScroll : bool with get, set
member CanVerticallyScroll : bool with get, set
member ExtentHeight : float
member ExtentWidth : float
member HorizontalOffset : float
member LineDown : unit -> unit
member LineLeft : unit -> unit
member LineRight : unit -> unit
member LineUp : unit -> unit
...
Full name: System.Windows.Controls.StackPanel
--------------------
StackPanel() : unit
Full name: Microsoft.FSharp.Core.Operators.ignore
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
type ItemView =
inherit View<Events,Label,ItemModel>
new : m:ItemModel -> ItemView
override SetBindings : m:ItemModel -> unit
override EventStreams : IObservable<Events> list
Full name: Tutorial.wpf.ItemView
--------------------
new : m:ItemModel -> ItemView
type View<'Event,'Element,'Model> =
inherit IViewWithModel<'Event,'Model>
new : elt:'Element * m:'Model -> View<'Event,'Element,'Model>
member Root : 'Element
Full name: FSharp.Qualia.View<_,_,_>
--------------------
new : elt:'Element * m:'Model -> View<'Event,'Element,'Model>
Full name: Tutorial.wpf.ItemView.EventStreams
Full name: Tutorial.wpf.ItemView.SetBindings
type ListModel =
new : unit -> ListModel
member Items : ObservableCollection<ItemModel>
member SelectedItem : ReactiveProperty<ItemModel option>
Full name: Tutorial.wpf.ListModel
--------------------
new : unit -> ListModel
type ObservableCollection<'T> =
inherit Collection<'T>
new : unit -> ObservableCollection<'T> + 2 overloads
member Move : oldIndex:int * newIndex:int -> unit
event CollectionChanged : NotifyCollectionChangedEventHandler
Full name: System.Collections.ObjectModel.ObservableCollection<_>
--------------------
ObservableCollection() : unit
ObservableCollection(list: System.Collections.Generic.List<'T>) : unit
ObservableCollection(collection: System.Collections.Generic.IEnumerable<'T>) : unit
type ReactiveProperty<'a> =
interface IObservable<'a>
new : init:'a -> ReactiveProperty<'a>
new : source:IObservable<'a> * init:'a -> ReactiveProperty<'a>
override ToString : unit -> string
member Value : 'a
member private sub : BehaviorSubject<'a>
member Value : 'a with set
Full name: FSharp.Qualia.ReactiveProperty<_>
--------------------
new : init:'a -> ReactiveProperty<'a>
new : source:System.IObservable<'a> * init:'a -> ReactiveProperty<'a>
type ListView =
inherit DerivedCollectionSourceView<Events,ListViewWindow,ListModel>
new : elt:ListViewWindow * m:ListModel -> ListView
override SetBindings : m:ListModel -> unit
override EventStreams : IObservable<Events> list
Full name: Tutorial.wpf.ListView
--------------------
new : elt:ListViewWindow * m:ListModel -> ListView
type DerivedCollectionSourceView<'Event,'Element,'Model (requires 'Element :> FrameworkElement)> =
inherit View<'Event,'Element,'Model>
new : elt:'Element * m:'Model -> DerivedCollectionSourceView<'Event,'Element,'Model>
member linkCollection : itemsControl:ItemsControl -> creator:('ItemModel -> 'ItemView) -> coll:ObservableCollection<'ItemModel> -> ICollectionView (requires equality and equality and 'ItemView :> IViewWithModel<'Event,'ItemModel>)
Full name: FSharp.Qualia.WPF.DerivedCollectionSourceView<_,_,_>
--------------------
new : elt:'Element * m:'Model -> DerivedCollectionSourceView<'Event,'Element,'Model>
Full name: Tutorial.wpf.ListView.EventStreams
module Observable
from FSharp.Qualia
--------------------
module Observable
from Microsoft.FSharp.Control
Full name: Microsoft.FSharp.Control.Observable.map
from Microsoft.FSharp.Core
Full name: Microsoft.FSharp.Core.Option.map
Full name: Microsoft.FSharp.Control.Observable.filter
type KeyEventArgs =
inherit KeyboardEventArgs
new : keyboard:KeyboardDevice * inputSource:PresentationSource * timestamp:int * key:Key -> KeyEventArgs
member DeadCharProcessedKey : Key
member ImeProcessedKey : Key
member InputSource : PresentationSource
member IsDown : bool
member IsRepeat : bool
member IsToggled : bool
member IsUp : bool
member Key : Key
member KeyStates : KeyStates
...
Full name: System.Windows.Input.KeyEventArgs
--------------------
Input.KeyEventArgs(keyboard: Input.KeyboardDevice, inputSource: PresentationSource, timestamp: int, key: Input.Key) : unit
| None = 0
| Cancel = 1
| Back = 2
| Tab = 3
| LineFeed = 4
| Clear = 5
| Return = 6
| Enter = 6
| Pause = 7
| Capital = 8
...
Full name: System.Windows.Input.Key
Full name: FSharp.Qualia.Observable.mapTo
Full name: Tutorial.wpf.ListView.SetBindings
Full name: Microsoft.FSharp.Control.Observable.add
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
type ListController =
interface IDispatcher<Events,ListModel>
new : unit -> ListController
Full name: Tutorial.wpf.ListController
--------------------
new : unit -> ListController
interface
abstract member InitModel : 'Model -> unit
abstract member Dispatcher : ('Event -> EventHandler<'Model>)
end
Full name: FSharp.Qualia.IDispatcher<_,_>
Full name: Tutorial.wpf.ListController.InitModel
Full name: Tutorial.wpf.ListController.Dispatcher
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
union case EventHandler.Async: ('Model -> Async<unit>) -> EventHandler<'Model>
--------------------
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
Full name: Microsoft.FSharp.Control.Async
--------------------
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
Full name: Microsoft.FSharp.Core.Option.iter
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
Full name: Tutorial.wpf.app
type Application =
inherit DispatcherObject
new : unit -> Application
member FindResource : resourceKey:obj -> obj
member MainWindow : Window with get, set
member Properties : IDictionary
member Resources : ResourceDictionary with get, set
member Run : unit -> int + 1 overload
member Shutdown : unit -> unit + 1 overload
member ShutdownMode : ShutdownMode with get, set
member StartupUri : Uri with get, set
member TryFindResource : resourceKey:obj -> obj
...
Full name: System.Windows.Application
--------------------
Application() : unit
Full name: Tutorial.wpf.lm
Full name: Tutorial.wpf.v
Full name: Tutorial.wpf.c
Full name: Tutorial.wpf.loop
type EventLoop<'Model,'Event,'Element> =
new : v:View<'Event,'Element,'Model> * c:IDispatcher<'Event,'Model> -> EventLoop<'Model,'Event,'Element>
member Inject : e:'Event -> unit
member Start : unit -> IDisposable
member StartWithScheduler : f:((unit -> unit) -> unit) -> IDisposable
Full name: FSharp.Qualia.EventLoop<_,_,_>
--------------------
new : v:View<'Event,'Element,'Model> * c:IDispatcher<'Event,'Model> -> EventLoop<'Model,'Event,'Element>
Application.Run(window: Window) : int
Application.Shutdown(exitCode: int) : unit