資料繫結和資料格視圖(DataGridView)控制項

來源:互聯網
上載者:User

標籤:datagridview   style   blog   tar   ext   c   

資料繫結和資料網格視圖(DataGridView)控制項

 

資料網格視圖控制項,不像我們前面看到的控制項,它可以顯示多個列,但是,資料必須格式化,使資料網格知道要顯示哪一列。有兩種實現方法:一個是把資料網格視圖綁定到資料表(DataTable),另一個是把網格到綁定對象列表,對象有許多屬性,不同的屬性就成為網格的列。

下面的例子是一種簡單的解決方案,綁定到資料集(DataSet):

 

open System

open System.Collections.Generic

open System.Configuration

open System.Data

open System.Data.SqlClient

open System.Windows.Forms

 

// creates a connections then executes thegiven command on it

let createDataSet commandString =

  //read the connection string

  letconnectionSetting =

    ConfigurationManager.ConnectionStrings.["MyConnection"]

  //create a data adapter to fill the dataset

  letadapter = new SqlDataAdapter(commandString, connectionSetting.ConnectionString)

  //create a new data set and fill it

  letds = new DataSet()

  adapter.Fill(ds)|> ignore

  ds

 

// create the data set that will be boundto the form

let dataSet = createDataSet "selecttop 10 * from Person.Contact"

 

// create a form containing a data bounddata grid view

let form =

  lettemp = new Form()

  letgrid = new DataGridView(Dock = DockStyle.Fill)

  temp.Controls.Add(grid)

  grid.DataSource<- dataSet.Tables.[0]

  temp

 

// show the form

Application.Run(form)

 

 

運行前面的代碼,可以看到 9-2 顯示的結果。

圖 9-2 綁定了資料的資料網格

 

若不使用 DataSet,還可以使用 F# 記錄類型。這樣,通常需要建立一個泛型函數(generic

function),通過反射(reflection)建立並發布強型別集合。下面的代碼示範了這種泛型函數,把它封裝在模組中,這樣,就能更方便地把它用於其他代碼,然後,用這個模組執行對資料庫的查詢:

 

module Strangelights.DataTools

open System

open System.Collections.Generic

open System.Configuration

open System.Data

open System.Data.SqlClient

open Microsoft.FSharp.Reflection

 

// a command that returns dynamicallycreated stongly typed collection

let execCommand<‘a> commandString :seq<‘a> =

  //the opener that executes the command

  letopener() =

    //read the connection string

    letconnectionSetting =

      ConfigurationManager.ConnectionStrings.["MyConnection"]

    //create the connection and open it

    letconn = new SqlConnection(connectionSetting.ConnectionString)

    conn.Open()

    //excute the command, ensuring the read will close the connection

    letcmd = conn.CreateCommand(CommandType = CommandType.Text,

                               CommandText = commandString)

    cmd.ExecuteReader(CommandBehavior.CloseConnection)

 

// the generator, that generates anstrongly typed object for each row

let generator (reader : IDataReader) =

  ifreader.Read() then

    //get the type object and its properties

    lett = typeof<‘a>

    //get the values for the row from the reader

    letvalues = Array.create reader.FieldCount (new obj())

    reader.GetValues(values)|> ignore

    letconvertVals x = match box x with | :? DBNull -> null | _ -> x

    letvalues = Array.map convertVals values

    //create the record and return it

    Some(FSharpValue.MakeRecord(t, values) :?> ‘a)

  else

    None

 

// generate the sequence

Seq.generate

  opener

  generator

  (funr -> r.Dispose())

 

例子代碼的第一行使用了一個我們之前尚未用到過的方法,顯式聲明了函數的型別參數:

 

let execCommand<‘a> commandString :seq<‘a>

 

這樣做,能夠顯式給定泛型參數‘a,這個型別參數然後用於建立類型對象,再對它做反射:

 

let t = typeof<‘a>

 

這個函數是用來處理 F# 記錄類型,它的欄位完全符合查詢結果的欄位;如果不滿足這個先決條件,代碼就失敗;然而,這個先決條件通常是在應用程式中以反射的形式使用的。

前面已經定義的泛型函數 execCommand,能夠用於任何查詢,匹配記錄類型。下面的代碼示範如何應用:

 

open System

open System.Windows.Forms

open Strangelights.DataTools

 

// a type that mirrors the type of rowbeing created

type Contact =

  {ContactID: Nullable<int>;

   NameStyle:Nullable<bool>;

   Title:string;

   FirstName:string;

   MiddleName:string;

   LastName:string;

   Suffix:string;

   EmailAddress:string;

   EmailPromotion:Nullable<int>;

   Phone:string;

   PasswordHash:string;

   PasswordSalt:string;

   AdditionalContactInfo:string;

   rowguid:Nullable<Guid>;

   ModifiedDate:Nullable<DateTime> }

 

// a form containing a data bound data grid

let form =

  lettemp = new Form()

  letgrid = new DataGridView(Dock = DockStyle.Fill)

  temp.Controls.Add(grid)

  letcontacts =

    execCommand<Contact>"select top 10 * from Person.Contact"

  letcontactsArray = contacts |> Seq.to_array

  grid.DataSource<- contactsArray

  temp

 

// show the form

Application.Run(form)

 

最重要的是下面一行:

 

let contacts =

  execCommand<Contact>"select top 10 * from Person.Contact"

 

為泛型函數 execCommand 顯式聲明了型別參數。這個例子的結果同前面的例子, 9-2 所示。

 

注意

使用對象-關係映射,比例NHibernate,執行這種任務已經相當普遍,這些工具提供了高度的靈活性,但它們往往過度依賴於純正 C# 的功能,要想在 F# 中使用,體驗並不良好,因此,我在書中沒有討論任何相關內容。但是,許多人,包括我自己正在努力解決這個問題;同時,建議你關注我的部落格:http://strangelights.com/blog。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.