问题描述
我编写了以下函数,以通过F#交互式查看网格中的数据:
I wrote the following function to view data in a grid from F# interactive:
open System.Windows.Forms
let grid x =
let form = new Form(Visible = true)
let data = new DataGridView(Dock = DockStyle.Fill)
form.Controls.Add(data)
data.DataSource <- x |> Seq.toArray
如何使它适用于1D和2D序列?例如,grid [1,2,3]
或grid[(1,0);(2,0);(3,0)];;
可以正常工作,但grid [1;2;3];;
不能工作.
How can I make it work for both 1D and 2D seqs? say, grid [1,2,3]
or grid[(1,0);(2,0);(3,0)];;
works fine but grid [1;2;3];;
would not work.
另一个问题是,为什么必须添加`|> Seq.toArray使其起作用?
another question is, why do I have to add the `|>Seq.toArray to make it work?
推荐答案
如desco所述,DataGridView
控件显示对象的属性值.
As desco explains, the DataGridView
control displays values of properties of the object.
对于原始类型来说,这是非常愚蠢的行为-例如,如果您将[ "Hello"; "world!" ]
指定为数据源,它将显示具有值5和6的列Length
.这绝对不是您想要的!
This is pretty silly behavior for primitive types - for example if you specify [ "Hello"; "world!" ]
as the data source, it will display column Length
with values 5 and 6. That's definitely not what you'd want!
我能找到的最佳解决方案是显式检查字符串和原始类型,并将它们包装为仅具有单个属性的简单类型(将显示):
The best solution I could find is to explicitly check for strings and primitive types and wrap them in a simple type with just a single property (that will get displayed):
type Wrapper(s:obj) =
member x.Value = s.ToString()
let grid<'T> (x:seq<'T>) =
let form = new Form(Visible = true)
let data = new DataGridView(Dock = DockStyle.Fill)
form.Controls.Add(data)
data.AutoGenerateColumns <- true
if typeof<'T>.IsPrimitive || typeof<'T> = typeof<string> then
data.DataSource <- [| for v in x -> Wrapper(box v) |]
else
data.DataSource <- x |> Seq.toArray
grid [ 1 .. 10 ]
grid [ "Hello"; "World" ]
这篇关于函数在F#中可视化网格中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!