[英]F# Winforms Charting Asynchronous Updating
我試圖在Winforms中創建一個圖表,該圖表將數據綁定到內存中的列表,並隨着列表的更改而動態更新。 這是我的代碼:
open System
open System.Linq
open System.Collections
open System.Collections.Generic
open System.Drawing
open System.Windows.Forms
open System.Windows.Forms.DataVisualization
open System.Windows.Forms.DataVisualization.Charting
let link = new LinkedList<double>()
let rnd = new System.Random()
for i in 1 .. 10 do link.AddFirst(rnd.NextDouble()) |> ignore
let series = new Series()
let chart = new System.Windows.Forms.DataVisualization.Charting.Chart(Dock = DockStyle.Fill, Palette = ChartColorPalette.Pastel)
series.Points.DataBindY(link)
let form = new Form(Visible = true, Width = 700, Height = 500)
form.Controls.Add(chart)
let formloop = async {
while not chart.IsDisposed do
link.AddFirst((new System.Random()).NextDouble()) |> ignore
link.RemoveLast()
}
do
Async.StartImmediate(formloop)
Application.Run(form)
Console.WriteLine("Done")
Console.ReadLine() |> ignore
異步似乎可以正常工作,但是圖表從不顯示任何內容。 它只是顯示一個空白窗口。 我究竟做錯了什么?
LinkedList<T>
無法表示已更新,因此Chart
無法知道何時重新繪制自身。
為了使數據綁定更新視圖,源列表必須實現IBindingList
並在內容更改時引發適當的事件。
另外,我必須指出,直接從非UI線程(例如,代碼中的chart.IsDisposed
)訪問UI屬性/方法很危險。 在WinForms中,很少實際實施此限制,因此有時這似乎可以很好地工作,但稍后會在客戶的計算機上崩潰,而無法附加調試器。
您需要將系列添加到圖表的SeriesCollection
。
chart.Series.Add series
您需要構造一個圖表區域並將其添加到圖表的ChartAreaCollection
。
let area = new ChartArea() chart.ChartAreas.Add area
您需要確保在設置圖表和表單之后調用數據綁定方法。
... form.Controls.Add chart series.Points.DataBindY link
而且,正如Fyodor Soikin的答案所述,現在無法將綁定集合的更改傳達給該系列的DataPointCollection
。 我不太確定IBindingList
是否合適。 盡管可以掛接到ListChanged
事件,但我們也可以直接操縱該系列的DataPointCollection
。
let formloop = async{ while not chart.IsDisposed do series.Points.RemoveAt 0 series.Points.AddY(rnd.NextDouble()) |> ignore do! Async.Sleep 100 }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.