DataBinding - 又是新標籤系統

  • 4760
  • 0

摘要:DataBinding - 又是新標籤系統

新標籤系統有一個畫面如下圖:

左邊的控制項是動態產生的,data source和右邊的grid view來源相同,以上圖為例都是從Products這個datatable取得。
需求是當users選了gird view其中一筆資料,左邊也要同步顯示相應的資料,如果users手動修改資料後也必須同步更新至grid view。這不就是傳說中的data binding嗎?

一步一步來實現吧!

  1. 首先說明控制項(上圖),左邊由上到的Name分別是uxName, uxType, uxFlow, uxNameFlow(內容=uxName.Text +uxFlow.Text),右邊的DataGridView則命名為uxProducts。
  2. 資料來源一般可能都是從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 });
    }
  3. 設定各控制項的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);
  4. 設定完後看起來都很ok,實際執行後點選grid view的一筆資料後,左邊的控制項內容也會同步更新,但是修改了左邊控制項的內容後會發現右邊的grid view並沒有同步更新,必須手動在grid view的空白處點一下才能讓grid view更新。因此必需在每個控制項的Validated事件呼叫DataGridView.Refresh()來強制更新:
    
    List controls = new List(new Control[] { this.uxName, this.uxType, this.uxFlow });
    foreach (Control ctrl in controls)
    {
        ctrl.Validated += this.ControlOnValidated;
    }
    
    private void ControlOnValidated(object sender, EventArgs e)
    {
        this.uxProducts.Refresh();
    }
  5. 這樣每當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;
    }

大功告成啦!