2 people like it.
Like the snippet!
SortableBindingList
SortableBindingList suitable for use with WinForms DataGridView.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
|
open System
open System.Collections.Generic
open System.ComponentModel
// SortableBindingList in F# adapted from msmolcic on Stack Overflow
// https://stackoverflow.com/questions/23661195/datagridview-using-sortablebindinglist
type SortableBindingList<'T>(list:IEnumerable<'T>) =
inherit BindingList<'T>(List(list))
let mutable isSorted = false
let mutable sortDirection = ListSortDirection.Ascending
let mutable sortProperty : PropertyDescriptor option = None
new () = SortableBindingList(Seq.empty<'T>)
override l.ApplySortCore(prop, direction) =
let raiseEx () =
new NotSupportedException("Cannot sort by " + prop.Name +
". This" + prop.PropertyType.ToString() + " does not implement IComparable")
|> raise
match prop.PropertyType.GetInterface("IComparable") with
| null ->
if prop.PropertyType.IsValueType then
match Nullable.GetUnderlyingType(prop.PropertyType) with
| null -> raiseEx()
| t ->
match t.GetInterface("IComparable") with
| null -> raiseEx()
| _ -> () // Just fall through the match case and apply the sort
| _ -> () // Just fall through the match case and apply the sort
// IComparable interface is supported, so apply the sort
let query = base.Items :> IEnumerable<'T>
sortProperty <- Some prop
sortDirection <- direction
let sorted =
match direction with
| ListSortDirection.Ascending ->
query |> Seq.sortBy (fun i -> prop.GetValue(i) :?> IComparable)
| _ ->
query |> Seq.sortByDescending (fun i -> prop.GetValue(i) :?> IComparable)
|> Array.ofSeq
// Can't access protected "Items" within lambda, so use this for loop construct
for i in [0 .. Array.length sorted - 1] do
l.Items.[i] <- sorted.[i]
isSorted <- true
l.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1))
override __.SortPropertyCore =
match sortProperty with
| Some sp -> sp
| _ ->
new System.NullReferenceException("Sortable property was null.")
|> raise
override __.SortDirectionCore = sortDirection
override __.SupportsSortingCore = true
override __.IsSortedCore = isSorted
|
namespace System
namespace System.Collections
namespace System.Collections.Generic
namespace System.ComponentModel
Multiple items
type SortableBindingList<'T> =
inherit BindingList<'T>
new : unit -> SortableBindingList<'T>
new : list:IEnumerable<'T> -> SortableBindingList<'T>
override ApplySortCore : prop:PropertyDescriptor * direction:ListSortDirection -> unit
override IsSortedCore : bool
override SortDirectionCore : ListSortDirection
override SortPropertyCore : PropertyDescriptor
override SupportsSortingCore : bool
Full name: Script.SortableBindingList<_>
--------------------
new : unit -> SortableBindingList<'T>
new : list:IEnumerable<'T> -> SortableBindingList<'T>
Multiple items
val list : IEnumerable<'T>
--------------------
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
type IEnumerable<'T> =
member GetEnumerator : unit -> IEnumerator<'T>
Full name: System.Collections.Generic.IEnumerable<_>
Multiple items
type BindingList<'T> =
inherit Collection<'T>
new : unit -> BindingList<'T> + 1 overload
member AddNew : unit -> 'T
member AllowEdit : bool with get, set
member AllowNew : bool with get, set
member AllowRemove : bool with get, set
member CancelNew : itemIndex:int -> unit
member EndNew : itemIndex:int -> unit
member RaiseListChangedEvents : bool with get, set
member ResetBindings : unit -> unit
member ResetItem : position:int -> unit
...
Full name: System.ComponentModel.BindingList<_>
--------------------
BindingList() : unit
BindingList(list: IList<'T>) : unit
Multiple items
type List<'T> =
new : unit -> List<'T> + 2 overloads
member Add : item:'T -> unit
member AddRange : collection:IEnumerable<'T> -> unit
member AsReadOnly : unit -> ReadOnlyCollection<'T>
member BinarySearch : item:'T -> int + 2 overloads
member Capacity : int with get, set
member Clear : unit -> unit
member Contains : item:'T -> bool
member ConvertAll<'TOutput> : converter:Converter<'T, 'TOutput> -> List<'TOutput>
member CopyTo : array:'T[] -> unit + 2 overloads
...
nested type Enumerator
Full name: System.Collections.Generic.List<_>
--------------------
List() : unit
List(capacity: int) : unit
List(collection: IEnumerable<'T>) : unit
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
val mutable isSorted : bool
val mutable sortDirection : ListSortDirection
type ListSortDirection =
| Ascending = 0
| Descending = 1
Full name: System.ComponentModel.ListSortDirection
field ListSortDirection.Ascending = 0
val mutable sortProperty : PropertyDescriptor option
type PropertyDescriptor =
inherit MemberDescriptor
member AddValueChanged : component:obj * handler:EventHandler -> unit
member CanResetValue : component:obj -> bool
member ComponentType : Type
member Converter : TypeConverter
member Equals : obj:obj -> bool
member GetChildProperties : unit -> PropertyDescriptorCollection + 3 overloads
member GetEditor : editorBaseType:Type -> obj
member GetHashCode : unit -> int
member GetValue : component:obj -> obj
member IsLocalizable : bool
...
Full name: System.ComponentModel.PropertyDescriptor
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
union case Option.None: Option<'T>
module Seq
from Microsoft.FSharp.Collections
val empty<'T> : seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.empty
val l : SortableBindingList<'T>
override SortableBindingList.ApplySortCore : prop:PropertyDescriptor * direction:ListSortDirection -> unit
Full name: Script.SortableBindingList`1.ApplySortCore
val prop : PropertyDescriptor
val direction : ListSortDirection
val raiseEx : (unit -> 'a)
Multiple items
type NotSupportedException =
inherit SystemException
new : unit -> NotSupportedException + 2 overloads
Full name: System.NotSupportedException
--------------------
NotSupportedException() : unit
NotSupportedException(message: string) : unit
NotSupportedException(message: string, innerException: exn) : unit
property MemberDescriptor.Name: string
property PropertyDescriptor.PropertyType: Type
Type.ToString() : string
val raise : exn:Exception -> 'T
Full name: Microsoft.FSharp.Core.Operators.raise
Type.GetInterface(name: string) : Type
Type.GetInterface(name: string, ignoreCase: bool) : Type
property Type.IsValueType: bool
Multiple items
type Nullable =
static member Compare<'T> : n1:Nullable<'T> * n2:Nullable<'T> -> int
static member Equals<'T> : n1:Nullable<'T> * n2:Nullable<'T> -> bool
static member GetUnderlyingType : nullableType:Type -> Type
Full name: System.Nullable
--------------------
type Nullable<'T (requires default constructor and value type and 'T :> ValueType)> =
struct
new : value:'T -> Nullable<'T>
member Equals : other:obj -> bool
member GetHashCode : unit -> int
member GetValueOrDefault : unit -> 'T + 1 overload
member HasValue : bool
member ToString : unit -> string
member Value : 'T
end
Full name: System.Nullable<_>
--------------------
Nullable()
Nullable(value: 'T) : unit
Nullable.GetUnderlyingType(nullableType: Type) : Type
val t : Type
val query : IEnumerable<'T>
union case Option.Some: Value: 'T -> Option<'T>
val sorted : 'T []
val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Seq.sortBy
val i : 'T
PropertyDescriptor.GetValue(component: obj) : obj
Multiple items
type IComparable =
member CompareTo : obj:obj -> int
Full name: System.IComparable
--------------------
type IComparable<'T> =
member CompareTo : other:'T -> int
Full name: System.IComparable<_>
val sortByDescending : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Seq.sortByDescending
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
val ofSeq : source:seq<'T> -> 'T []
Full name: Microsoft.FSharp.Collections.Array.ofSeq
val i : int
val length : array:'T [] -> int
Full name: Microsoft.FSharp.Collections.Array.length
property Collections.ObjectModel.Collection.Items: IList<'T>
BindingList.OnListChanged(e: ListChangedEventArgs) : unit
Multiple items
type ListChangedEventArgs =
inherit EventArgs
new : listChangedType:ListChangedType * newIndex:int -> ListChangedEventArgs + 3 overloads
member ListChangedType : ListChangedType
member NewIndex : int
member OldIndex : int
member PropertyDescriptor : PropertyDescriptor
Full name: System.ComponentModel.ListChangedEventArgs
--------------------
ListChangedEventArgs(listChangedType: ListChangedType, newIndex: int) : unit
ListChangedEventArgs(listChangedType: ListChangedType, propDesc: PropertyDescriptor) : unit
ListChangedEventArgs(listChangedType: ListChangedType, newIndex: int, propDesc: PropertyDescriptor) : unit
ListChangedEventArgs(listChangedType: ListChangedType, newIndex: int, oldIndex: int) : unit
type ListChangedType =
| Reset = 0
| ItemAdded = 1
| ItemDeleted = 2
| ItemMoved = 3
| ItemChanged = 4
| PropertyDescriptorAdded = 5
| PropertyDescriptorDeleted = 6
| PropertyDescriptorChanged = 7
Full name: System.ComponentModel.ListChangedType
field ListChangedType.Reset = 0
override SortableBindingList.SortPropertyCore : PropertyDescriptor
Full name: Script.SortableBindingList`1.SortPropertyCore
val sp : PropertyDescriptor
Multiple items
type NullReferenceException =
inherit SystemException
new : unit -> NullReferenceException + 2 overloads
Full name: System.NullReferenceException
--------------------
NullReferenceException() : unit
NullReferenceException(message: string) : unit
NullReferenceException(message: string, innerException: exn) : unit
val __ : SortableBindingList<'T>
override SortableBindingList.SortDirectionCore : ListSortDirection
Full name: Script.SortableBindingList`1.SortDirectionCore
override SortableBindingList.SupportsSortingCore : bool
Full name: Script.SortableBindingList`1.SupportsSortingCore
override SortableBindingList.IsSortedCore : bool
Full name: Script.SortableBindingList`1.IsSortedCore
More information