摘要:DataBinding - 又是新標籤系統
新標籤系統有一個畫面如下圖:
左邊的控制項是動態產生的,data source和右邊的grid view來源相同,以上圖為例都是從Products這個datatable取得。
需求是當users選了gird view其中一筆資料,左邊也要同步顯示相應的資料,如果users手動修改資料後也必須同步更新至grid view。這不就是傳說中的data binding嗎?
一步一步來實現吧!
- 首先說明控制項(上圖),左邊由上到的Name分別是uxName, uxType, uxFlow, uxNameFlow(內容=uxName.Text +uxFlow.Text),右邊的DataGridView則命名為uxProducts。
-
資料來源一般可能都是從database下SQL query取得的,不過為了方便說明所以我就手動建立假資料:
// Create table schema DataTable dt = new DataTable("Products"); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Type", typeof(string)); dt.Columns.Add("Flow", typeof(string)); dt.Columns.Add("NameFlow", typeof(string)); // Insert data rows List types = new List(new string[] { "TopCore", "BottomCore", "ExtrudedTube" }); Random rnd = new Random((int)DateTime.Now.Ticks & 0x0000FFFF); for (int index = 1; index <= 10; index++) { dt.Rows.Add(new object[] { string.Format("Prod{0}", index.ToString("000")), types[rnd.Next(0, 3)], "Flow1", string.Empty }); } -
設定各控制項的binding:
// Grid Databinding this.uxProducts.DataSource = dt; // ComboBox Databinding this.uxType.DataBindings.Add("Text", dt, "Type"); // TextBox Databinding this.uxName.DataBindings.Add("Text", dt, "Name"); this.uxFlow.DataBindings.Add("Text", dt, "Flow"); this.uxNameFlow.DataBindings.Add("Text", dt, "NameFlow", false, DataSourceUpdateMode.OnPropertyChanged); -
設定完後看起來都很ok,實際執行後點選grid view的一筆資料後,左邊的控制項內容也會同步更新,但是修改了左邊控制項的內容後會發現右邊的grid view並沒有同步更新,必須手動在grid view的空白處點一下才能讓grid view更新。因此必需在每個控制項的Validated事件呼叫DataGridView.Refresh()來強制更新:
Listcontrols = new List private void ControlOnValidated(object sender, EventArgs e) { this.uxProducts.Refresh(); }(new Control[] { this.uxName, this.uxType, this.uxFlow }); foreach (Control ctrl in controls) { ctrl.Validated += this.ControlOnValidated; } -
這樣每當users修改完資料並將焦點移開(觸發該控制項的validate),就會發現grid view也同步更新了,最後,因為uxNameFlow這個控制項的內容是由uxName和uxFlow所組成,所以當這兩個控制項的內容有異動時他也要 同時更新,因此必需在uxName和uxFlow的TextChanged事件寫一些code:
private void uxName_TextChanged(object sender, EventArgs e) { this.uxNameFlow.Text = this.uxName.Text + this.uxFlow.Text; } private void uxFlow_TextChanged(object sender, EventArgs e) { this.uxNameFlow.Text = this.uxName.Text + this.uxFlow.Text; }
大功告成啦!