3 people like it.
Like the snippet!
Structural BeginUpdate / EndUpdate with Lambda
Several WinForms controls, like TreeView and ListView, implement methods BeginUpdate and EndUpdate, which suspend repainting of the control while items are being individually added to a control, preventing flicker caused by rapid repainting.
But using BeginUpdate and EndUpdate is very imperative, and opens up the possibility for bugs, such as neglecting to call the matching EndUpdate. An obvious improvement would be to create an extension method on types implementing this pattern which takes a unit -> unit lambda which is executed between update pairs.
But the pattern is only conventional, rather than through a common base class or interface. Hence this presents a reasonable opportunity to use F#'s statically resolved structural type system to implement a function which only works on Control types with the correct structural signature.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
|
module Control =
let inline update< ^a when ^a :(member BeginUpdate: unit -> unit)
and ^a : (member EndUpdate: unit -> unit)> (this: ^a) f =
(^a : (member BeginUpdate: unit -> unit) (this))
f()
(^a : (member EndUpdate: unit -> unit) (this))
module Example =
open System.Windows.Forms
let tv = new TreeView()
Control.update tv <| fun () ->
for i in 1..20 do
tv.Nodes.Add(new TreeNode(i |> string)) |> ignore
|
namespace Microsoft.FSharp.Control
val update : this:'a -> f:(unit -> unit) -> unit (requires member BeginUpdate and member EndUpdate)
Full name: Script.Control.update
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
val this : 'a (requires member BeginUpdate and member EndUpdate)
val f : (unit -> unit)
module Example
from Script
namespace System
namespace System.Windows
namespace System.Windows.Forms
val tv : TreeView
Full name: Script.Example.tv
Multiple items
type TreeView =
inherit Control
new : unit -> TreeView
member BackColor : Color with get, set
member BackgroundImage : Image with get, set
member BackgroundImageLayout : ImageLayout with get, set
member BeginUpdate : unit -> unit
member BorderStyle : BorderStyle with get, set
member CheckBoxes : bool with get, set
member CollapseAll : unit -> unit
member DrawMode : TreeViewDrawMode with get, set
member EndUpdate : unit -> unit
...
Full name: System.Windows.Forms.TreeView
--------------------
TreeView() : unit
Multiple items
type Control =
inherit Component
new : unit -> Control + 4 overloads
member AccessibilityObject : AccessibleObject
member AccessibleDefaultActionDescription : string with get, set
member AccessibleDescription : string with get, set
member AccessibleName : string with get, set
member AccessibleRole : AccessibleRole with get, set
member AllowDrop : bool with get, set
member Anchor : AnchorStyles with get, set
member AutoScrollOffset : Point with get, set
member AutoSize : bool with get, set
...
nested type ControlAccessibleObject
nested type ControlCollection
Full name: System.Windows.Forms.Control
--------------------
Control() : unit
Control(text: string) : unit
Control(parent: Control, text: string) : unit
Control(text: string, left: int, top: int, width: int, height: int) : unit
Control(parent: Control, text: string, left: int, top: int, width: int, height: int) : unit
val i : int32
property TreeView.Nodes: TreeNodeCollection
TreeNodeCollection.Add(node: TreeNode) : int
TreeNodeCollection.Add(text: string) : TreeNode
TreeNodeCollection.Add(key: string, text: string) : TreeNode
TreeNodeCollection.Add(key: string, text: string, imageKey: string) : TreeNode
TreeNodeCollection.Add(key: string, text: string, imageIndex: int) : TreeNode
TreeNodeCollection.Add(key: string, text: string, imageKey: string, selectedImageKey: string) : TreeNode
TreeNodeCollection.Add(key: string, text: string, imageIndex: int, selectedImageIndex: int) : TreeNode
Multiple items
type TreeNode =
inherit MarshalByRefObject
new : unit -> TreeNode + 4 overloads
member BackColor : Color with get, set
member BeginEdit : unit -> unit
member Bounds : Rectangle
member Checked : bool with get, set
member Clone : unit -> obj
member Collapse : unit -> unit + 1 overload
member ContextMenu : ContextMenu with get, set
member ContextMenuStrip : ContextMenuStrip with get, set
member EndEdit : cancel:bool -> unit
...
Full name: System.Windows.Forms.TreeNode
--------------------
TreeNode() : unit
TreeNode(text: string) : unit
TreeNode(text: string, children: TreeNode []) : unit
TreeNode(text: string, imageIndex: int, selectedImageIndex: int) : unit
TreeNode(text: string, imageIndex: int, selectedImageIndex: int, children: TreeNode []) : unit
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
More information