функция для визуализации данных в сетке в F # - PullRequest
0 голосов
/ 15 февраля 2011

Я написал следующую функцию для просмотра данных в сетке из F # интерактивного:

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];; не будет работать.

Другой вопрос: почему я должен добавить `|> Seq.toArray, чтобы он работал?

Ответы [ 2 ]

4 голосов
/ 15 февраля 2011

DataGridView использует привязку данных, которая отражает свойства объекта и отображает их в столбцах сетки (возможно, автоматически выводится). [1,2,3] и [(1,0); (2,0); (3,0)] являются списками кортежей, поэтому DataGridView может отображать компоненты кортежей. Как и наоборот, [1; 2; 3] - список целых чисел, он не содержит никаких свойств, которые выставляют фактическое значение.

Seq.ToArray необходим, поскольку DataSource ожидает IList, IListSource, IBindingList или IBindingListView ( DataGridView.DataSource Свойство ). Массив реализует IList, список F # - нет.

2 голосов
/ 15 февраля 2011

Как объясняет desco, элемент управления DataGridView отображает значения свойств объекта.

Это довольно глупое поведение для примитивных типов - например, если вы укажете [ "Hello"; "world!" ] в качестве источника данных, он будет отображать столбец Length со значениями 5 и 6. Это определенно не то, что вам нужно!

Лучшее решение, которое я смог найти, - это явно проверить строки и примитивные типы и обернуть их в простой тип только одним свойством (которое будет отображаться):

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" ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...