日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于BindingSource的WinForm开发

發布時間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于BindingSource的WinForm开发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.引言

BindingSource組件是數據源和控件間的一座橋,同時提供了大量的API和Event供我們使用。使用這些API我們可以將Code與各種具體類型數據源進行解耦;使用這些Event我們可以洞察數據的變化。

2.簡單綁定

DataTable myTable = myTableAdapter.GetData();//創建Table

BindingSource myBindingSource= new BindingSource();//創建BindingSource

DataGridView myGrid = new DataGridView();//創建GridView

myGrid.DataSource = myBindingSource;//將BindingSource綁定到GridView

myTable;//綁定數據到BindingSource

注:

1)綁定到DataTable,其實是綁定到DataTable提供的DataView上。每個DataTable都有一個缺省的DataView

2)DataView是綁定的實質,正如其名,它是DataTable的數據的展現。因此可以對同一個DataTable

,構建多個DataView,進而可以對這同樣的數據實施不同的過濾、排序等方法,從不同側面展示DataTable。這也體現了一定的MVC思想。

3)BindingSouce也可作為數據(其實是數據引用)的容器在不同窗體間傳遞,從而實現在彈出窗體中對數據的編輯

3.主細表

以上圖所示數據為例:

1)DataSet:myDataSet

2)DataTable:ParentTable、ChildTable、GrandChildTable

3)Relation:FK_Parent_Child、FK_Child_GrandChild

//綁定父數據

parentBindingSource.DataSource = myDataSet;

parentBindingSource.DataMember = "ParentTable";

m_GrandParentGrid.DataSource = m_GrandParentBindingSource;

//綁定子數據。
childBindingSource.DataSource = parentBindingSource;//綁定到“父BindingSource”,而不是父Table

childBindingSource.DataMember = "FK_Child_GrandChild";//綁定到“父-子Relation”

//綁定孫子數據。
grandChildBindingSource.DataSource = childBindingSource;//綁定到“子BindingSource”

grandChildBindingSource.DataMember = "FK_Child_GrandChild";//綁定到“子-孫Relation”

這樣你就可以在Form上擺上3個DataView,分布綁定到這3個BindingSouce,很容易就實現了主細表關聯展現。

4.數據操縱

要操縱數據,首先需要獲取當前數據項。BindingSource的Current屬性返回DataRowView類型的對象(就像DataView是對DataTable的封裝一樣,DataRowView是對DataRow的封裝),它是對當前數據項的封裝,可以通過類型轉換變成你想要的對象。

DataRowView currentRowView = myBindingSource.Current;//獲取當前RowView

CustomersRow custRow = currentRowView.Row as CustomersRow;//類型轉換為當前數據項

string company = custRow.CompanyName;//使用當前數據項

string phoneNo = custRow.Phone;

5.用BindingSource做數據容器

BindingSource還可以用作數據容器,即便它沒有綁定到數據源上,它內部有一個可以容納數據的list。

5.1Add方法

調用Add方法會在BindingSource的list中插入數據項。如果這時第一次插入數據,并且沒有綁定數據,那么插入數據的類型就決定了今后此list中數據的類型。

注:

1)此時再插入其它類型對象會拋出InvalidOperationException異常

2)設置DataSource屬性時會刷新list,造成Add方法添加到list中的數據丟失

5.2AddNew方法

AddNew方法返回BindingSourc所容納數據類型的對象;如果之前沒有容納數據,則會返回Object對象。

AddNew方法會調用EndEdit方法,并將提交對當前數據的操縱;然后新數據項就成為當前項。

AddNew方法會引發AddingNew事件,可以在此事件中為數據項賦值,或者創建新數據項

private void OnAddingNew(object sender, AddingNewEventArgs e)
{
????? e.NewObject = new MyCustomObject();//
}

6.用BindingSource對數據排序、過濾、搜索

6.1 Sort

為Sort屬性賦上Sort表達式,可以對數據進行排序

myBindingSource.Sort = "ContactName ASC";//對ContanctName列按ASC進行排序

myBindingSource.Sort = "Region ASC, CompanyName DESC"//先按Region、再按CompanyName排序

6.2 Find

Find方法根據指定屬性和關鍵字進行查找,并返回第一個匹配對象的Index
int index = m_CustomersBindingSource.Find("CompanyName",IBM);//按CompanyName查找IBM
if (index != -1)
{
??? myBindingSource.Position = index;//定位BindingSource
}

6.3 Filter

為Filter屬性賦上表達式,可以對數據進行過濾

m_CustomersBindingSource.Filter = "Country = 'Germany'";//過濾出Country屬性為Germany的數據

7.用Event監控數據

7.1 Event

1)AddingNew

調用AddNew()方法時觸發。

2)BindingComplete

當控件完成數據綁定時觸發,說明控件已經從數據源中讀取當前數據項的值。當BindingSource重新綁定或當前數據項改變時,會觸發此事件

注:

  • 當有多個控件綁定到同一數據源時,這個事件會觸發多次

3)CurrrentChanged

當前數據項改變時觸發此事件。觸發此事件的情況如下

  • Position屬性改變時
  • 添加、刪除數據時
  • DataSource或DataMember屬性改變時

4)CurrentItemChanged

當前數據項的值改變時觸發

5)DataError

通常輸入無效數據時,由CurrencyManage拋出異常,從而觸發此事件。

6)PositionChanged

Position屬性改變時觸發此事件。

7)ListChanged

數據集合改變時觸發。觸發此事件的情況如下

  • adding, editing, deleting, 或 moving 數據項時

改變那些會影響List行為特征的屬性時,如AllowEdit屬性

  • 替換List時(綁到新數據源)

8.限制數據修改

BindingSource不僅是數據源與控件間的“橋梁”,同時也是數據源的“看門人”。通過BindingSource,我們可以控制對數據的修改。

BinidingSource的AllowEdit, AllowNew和AllowRemove屬性可以控制客戶端代碼和控件對數據的修改

9.復雜數據類型的Binding

對于String類型的數據,直接Binding到Text控件即可,對于復雜類型有下面幾種情況

  • 對于DateTime、Image等類型的數據,它們存儲的格式與顯示要求并不一致。
  • 有時,你并不想顯示客戶ID,而是希望顯示客戶名稱
  • 數據庫中的Null值

9.1 Binding類

解決以上問題的關鍵是要理解Binding類,了解它是如何控制數據Binding的過程。

DataTable table = customersDataSet.Customers;

//將TextBox的Text屬性Binding到table的CustomerID列
customerIDTextBox.DataBindings.Add("Text", table,"CustomerID", true);

//上面一行代碼等同下面兩行代碼

Binding customerIDBinding = new Binding("Text", table,"CustomerID", true);
customerIDTextBox.DataBindings.Add(customerIDBinding);

從代碼可以看出,Binding是數據源(table)和控件(customerIDTextBox)間的中介人,它有以下功能

  • 從數據源取數據,并按照控件要求的數據類型對此數據進行格式化(Formatting),然后傳給控件
  • 從控件取數據,并按照數據源的數據類型要求對此數據進行解析(Parsing),然后返回給數據源
  • 自動對數據進行格式轉換

9.2Binding類構造函數和屬性

Binding構造函數有多個重載版本,下面介紹其重要的參數,這些參數同時存在于Binding對象的屬性中。下面介紹中,參數名和屬性名都列出來

1)formattingEnabled(屬性FormattingEnabled)

  • ?
    • true,Binding對象自動在數據源類型和控件要求的類型間進行轉換
    • false,反之

2)dataSourceUpdateMode

決定控件上數值的改變在何時提交回數據源

3)nullValue

DBNull、 null和Nullab<T>對應的值。

4)formatString

格式轉換

5)formatInfo

一個實現IFormatProvider接口的對象引用,用來自定義格式轉換

要了解類型如何轉換的,請學習Type Conversions and Format Providers相關內容。關于上面屬性的應用,請看下面介紹

9.3基于Binding類的內置機制(屬性、參數)進行類型轉換

通過Binding類構造時的參數,或屬性設置,可以控制它進行類型轉換的機制。

1)DateTime

下面先介紹一個DateTime類型的例子,使用DateTimePicker控件

//創建Binding,設置formattingEnabled為true

birthDateTimePicker.DataBindings.Add("Value",m_EmployeesBindingSource, "BirthDate", true);

//設定為使用自定義格式
birthDateTimePicker.Format = DateTimePickerFormat.Custom;

//設定格式
birthDateTimePicker.CustomFormat = "MM/dd/yyyy";

2)Numeric

salaryTextBox.DataBindings.Add("Text", employeesBindingSource,"Salary", true,? DataSourceUpdateMode.OnValidation,"<not specified>", "#.00");

以上代碼做了以下處理

  • 設定formattingEnabled為true:代表自動類型轉換
  • 設定DataSourceUpdateMode為OnValidation:
  • 設定nullValue為"<not specified>":這些DBNull就顯示為,"<not specified>", 同時用戶錄入,"<not specified>"時,數據值為DBNull
  • 設定formatString為"#.00":數值保留2位小數

9.4. 事件

下面介紹Binding的主要事件,以及如何基于這些事件進行類型轉換的控制。

主要事件:

1)Format事件

發生在從數據源獲取數據后,控件顯示此數據之前。在這個事件里將數據源的數據類型轉換為控件要求的數據類型。

2)Parse事件

與Event相反。它發生控件值改變后,數據更新回數據源之前。在這個事件里將控件的數據類型轉換為數據源要求的數據類型。

這兩個事件為我們控制數據提供了機制,它們都聲明為ConvertEventHandler類型,

void ConvertEventHandler(object sender, ConvertEventArgs e);

有兩個參數,第二個參數ConvertEventArgs e 提供了我們要formatting和parsing的數據。它有兩個屬性

  • e.DesiredType是數值要轉換的目標類型
  • e.Value是要轉換的數值。我們可以替換此Value

9.5. 基于事件的類型轉換

9.5.1 處理Format Event

void OnCountryFromFormat(object sender, ConvertEventArgs e)
{
??? if (e.Value == null || e.Value == DBNull.Value)
??? {
???????? pictureBox.Image = null;
???????? return;
??? }

??? //綁定的是數據源的CountryID字段,因此e.Value返回的ID號,通過此ID號取得對應數據行
??? CountriesRow countryRow =??? GetCountryRow((int)e.Value);

???? //將e.Value賦值為CountryName,從而在控件中顯示名稱
???? e.Value = countryRow.CountryName;
??? // 數據轉換

??? ImageConverter converter = new ImageConverter();
??? pictureBox.Image =??? converter.ConvertFrom(countryRow.Flag) as Image;
}

9.5.2 處理Format Event

void OnCountryFromParse(object sender, ConvertEventArgs e)
{
// Need to look up the Country information for the country name
ExchangeRatesDataSet.CountriesRow row =
GetCountryRow(e.Value.ToString());
if (row == null)
{
string error = "Country not found";
m_ErrorProvider.SetError(m_CountryFromTextBox, error);
m_CountryFromTextBox.Focus();
throw new ArgumentException(error);
}
e.Value = row.CountryID;
}

10 完成數據編輯

經常會遇到這種情況,你在一個控件中錄入或選擇一些數據,只有當年離開此控件時,關聯的數據才能同步更新。這個問題是由DataRow內部機制決定的。

DataRowView類實現IEditableObject接口,支持對象的事務性編輯(當你確認完成編輯前,可以回滾數據)。我們通過BeginEdit()方法來開始數據編輯,通過EndEdit()方法提交編輯。

不要將DataRowView的EndEdit()與DataSet、DataTable、DataRow的AcceptChanges()方法混淆。DataRow有original和current版本,同時IEditableObject的caching機制讓它有transient版本,在調用EndEdit()方法前,數據修改是不會提交到數據源。這就是前面問題的內在原因。

如果希望編輯的數據立即提交,那調用EndEdit()函數的最佳位置就是Validated事件。Validate事件在控件錄入的數據parsed,并且通過validate后觸發,在這個事件中觸發EndEdit()就會通知綁定到同一數據源的所有控件,從而實現數據同步更新。

private void OnCountryTextValidated(object sender, EventArgs e)
{
????????? exchangeRatesBindingSource.EndEdit();
}

當然,當前數據項改變時,也會觸發EndEdit()事件

11 使用AutoComplete

當你希望TexbBox或ComboBox中會自動提示功能,那你應該學習一下AutoComplete功能。下面以TextBox為例介紹相關步驟

1)設定TextBox的AutoCompleteSource屬性:FileSystem, HistoryList, RecentlyUsedList

2)如果希望使用自定義的列表,則設定AutoCompleteSource屬性為CustomSource

3)設定AutoCompleteMode為SuggestAppend。這意味著你輸入部分字符時,控件在下拉列表中提示所有相近的數據

4)如果不想使用內置的提示源,你可以自己創建一個AutoCompleteStringCollection類的列表,

5)創建這個列表后,將它賦給TextBox的AutoCompleteCustomSourc屬性

12 DataBinding的生命周期

BindingSource的DataSourceUpdateMode屬性是關鍵,它有以下三種可能值,下面分布以TextBox控件為例介紹此屬性不同時DataBinding的生命周期

1)OnValidating(缺省值)

  • DataBinding的生命周期:

TextBox.Leave, TextBox.Validating, Binding.Parse, TextBox.Validated

  • 此時若將控件的CausesValidation屬性設為false,那么Validating事件就不會發生

2)OnPropertyChanged

  • DataBinding的生命周期:

此時,每次控件值發生改變時都會觸發Binding.Parse。對TextBox控件來說,每次錄入字符都會觸發Binding.Parse。

3)Never

此時Parse事件不會觸發,也就是說控件將成為只讀的。

13 子父綁定

前面介紹了主細綁定,它其實是一個父子綁定。有時我們希望由子到父的關聯綁定,下面我們就一起來實現這個機制。實現這個機制的關鍵還是Event,這個Event就是BindingSource的CurrentChanged事件

private void OnCurrentChanged(object sender, EventArgs e)
????? {
???????? // 獲取當前的子DataRow
???????? ExchangeRatesDataSet.ExchangeRatesRow currentRow =
??????????? (ExchangeRatesDataSet.ExchangeRatesRow)
??????????? ((DataRowView)m_ExchangeRatesBindingSource.Current).Row;

???????? // 獲取關聯的父DataRow
???????? ExchangeRatesDataSet.CountriesRow fromCountryRow =
??????????? currentRow.CountriesRowByFK_ExchangeRates_CountriesFrom;
???????? ExchangeRatesDataSet.CountriesRow toCountryRow =
??????????? currentRow.CountriesRowByFK_ExchangeRates_CountriesTo;

???????? //顯示父DataRow的信息

???????? if (fromCountryRow != null && toCountryRow != null)
???????? {
??????????? m_FromCountryCombo.SelectedValue = fromCountryRow.CountryID;
??????????? m_ToCountryCombo.SelectedValue = toCountryRow.CountryID;
???????? }

}

14 綁定到數據的多個復本

有時,我們希望以不同角度看到同一數據,這時需要綁定到同一數據的多個復本。這里的關鍵是CurrencyManager類,每個BindingSource管理著一個CurrencyManager。如果多個控件綁定到同一個BindingSource,那么只有一個CurrencyManager,因此也就只有一個CurrentItem,這樣就造成這些綁定到同一BindingSource的控件同步刷新。要解決這個問題,我們需要多個CurrencyManager,也就是說我們可以創建多個BindingSource,且綁定到同一個數據源。

?轉自http://blog.csdn.net/cdhql/article/details/6129911

轉載于:https://www.cnblogs.com/yaojunyi/archive/2012/06/14/2549709.html

總結

以上是生活随笔為你收集整理的基于BindingSource的WinForm开发的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 在线观看一区二区三区四区 | 成人污污视频在线观看 | 人人干夜夜操 | 国产成人精品一区二区无码呦 | av看片| av在线导航 | 91精品人妻一区二区三区 | 国产午夜精品理论片在线 | 日韩aⅴ在线观看 | 国产在线播放一区二区三区 | 毛片基地免费 | 亚洲色图第一页 | 麻豆chinese极品少妇 | 免费黄色美女网站 | 亚洲免费一级 | 国产在线观看无码免费视频 | 男女av网站 | 久久精品一区二区三区黑人印度 | 有码中文字幕 | 亚洲视频在线视频 | 亚洲av无码久久精品色欲 | 青青操国产 | 成人一级片视频 | 国产一区二区91 | 国产成人精品a视频一区 | 五月色综合 | 日韩二区三区四区 | 少妇粉嫩小泬喷水视频www | 台湾swag在线播放 | 麻豆性视频 | 美女洗澡无遮挡 | 尤物视频在线观看国产性感 | 日韩特级黄色片 | 日韩欧美亚洲国产 | 色婷婷视频在线 | 男女国产视频 | 久久青青操 | 超碰在线人人草 | 成人动态视频 | 最近中文字幕免费视频 | 狠狠的日 | 欧美激情一区二区 | 粉嫩av一区 | 6080亚洲精品一区二区 | 免费在线观看不卡av | 色涩涩 | 成人一级影片 | 小明成人免费视频 | 偷拍女澡堂一区二区三区 | 综合久久久久久久久久久 | 欧美肥老妇| 国产日韩欧美91 | 日本视频www | 久久亚洲AV成人无码国产野外 | 久艹在线观看视频 | 久久久夜夜夜 | 在线伊人网 | av在线专区 | 91日韩一区二区 | 国产一级网站 | 精品一区二区视频 | www.久久视频 | 色婷视频| 久久久久亚洲精品中文字幕 | 亚洲av日韩av在线观看 | 毛片视频观看 | 激情午夜天 | 色妞视频| 国产亚洲一区二区在线 | 少妇把腿扒开让我舔18 | 亚洲人吸女人奶水 | 国产精品日日夜夜 | 欧洲久久久 | 2021国产在线视频 | 美女啪啪网址 | 欧美激情动态图 | 多毛的亚洲人毛茸茸 | 欧美色呦呦 | 日韩三级电影网址 | 免费人成在线 | 人人妻人人澡人人爽欧美一区双 | 香蕉视频网页版 | 亚洲国产看片 | 九九视频免费在线观看 | 中文字幕在线免费看线人 | 特黄aaaaaa私密按摩 | 丁香婷婷深情五月亚洲 | 啪啪精品| 黄色国产一级片 | 深夜激情网 | 欧美日韩一区二区三区四区五区六区 | 国产免费av一区二区 | aaa黄色片| 制服丝袜av在线播放 | 亚洲国产精品成人 | 亚洲一区二区激情 | 久久免费一级片 | 国产亚洲在线观看 | 人妻少妇偷人精品久久性色 |