I have an array of sample information that is constantly refreshed in a background thread.
Currently I am constantly assigning this array to a datagrid's ItemsSource property using a DispatcherTimer. That works but it resets any visual locations, for instance if the user places his cursor in the middle of the datagrid the execution timer will undo such position.
Is it possible to use a INotifyPropertyChanged or INotifyCollectionChanged event for this instead to prevent such situations to occur? If so, how does this work with F#?
I suppose I have to execute some function notifying the datagrid every time when there is an update of the array. The updating of the array is not in the STAThread section.
I am running VS2010 with the latest WPF toolkit containing the WPF datagrid.
You can use an ObservableCollection which will implements INotifyCollectionChanged for you. The F# looks something like this:
open System
open System.Collections.ObjectModel
open System.Windows
open System.Windows.Controls
open System.Windows.Threading
[<EntryPoint; STAThread>]
let Main args =
let data = ObservableCollection [0 .. 9]
let list = ListBox(ItemsSource = data)
let win = Window(Content = list, Visibility = Visibility.Visible)
let rnd = Random()
let callback =
EventHandler(fun sender args ->
let idx = rnd.Next(0, 10)
data.[idx] <- rnd.Next(0, 10)
)
let ts = TimeSpan(1000000L)
let dp = DispatcherPriority.Send
let cd = Dispatcher.CurrentDispatcher
let timer = DispatcherTimer(ts, dp, callback, cd) in timer.Start()
let app = Application() in app.Run(win)
Unfortunately Reflector shows that System.Windows.Controls.ItemsControl.OnItemCollectionChanged method removes the selection when it is called, so you may need to work around this default behaviour.
You can also implement INotifyPropertyChanged like so:
open System.ComponentModel
type MyObservable() =
let mutable propval = 0.0
let evt = Event<_,_>()
interface INotifyPropertyChanged with
[<CLIEvent>]
member this.PropertyChanged = evt.Publish
member this.MyProperty
with get() = propval
and set(v) = propval <- v
evt.Trigger(this, PropertyChangedEventArgs("MyProperty"))
Implementing INotifyCollectionChanged would work similarly.
best of luck,
Danny
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With