none
請教個關於DataBinding的問題 RRS feed

  • 問題

  • VS2008 sp1
    XP sp3
    window form應用程式

    我有兩個UserContol分別為UserContol1 及 UserContol2
    在這兩個上面分別有1個TextBox, 1個NumericUpDown 1個CheckBOx
    由於在這兩個UserControl上的資料要一致,所以我在新增一個Class,在此Class中有3個屬性對應到上面三個值。
    並在UserControl1及2中分別加入DataBindings,其程式碼如下:
    我測試的結果。在UserControl1上分別變更NumericUpDown及CheckBox的值,UserControl2會跟著變。
    但TextBox的值就不會變更。

    目的:就是要讓這兩個usercontrol上的值保持一致。
    問題一:請問我這樣子的作法,觀念上是否正確。
    問題二:為什麼TextBox無法跟著變?
    問題三:是否有其它較簡單的作法。

    感謝回覆

    public class myClass
    {
       public string TextString
      {
         get;
         set;
      }
      public int IntValue
      {
         get;
         set;
      }
      public bool boolValue
      {
         get;
         set;
      }
    }

    myClass _myClass = null;
    pubic UserContol1(myClass class)
    {
      _myClass = class;
      textBox1.DataBindings.Add("Text", _myClass, "TextString", true);
      numericUpdDown1.DataBindings.Add("Text", _myClass, "IntValue", true);
      checkBox1.DataBindings.Add("Text", _myClass, "boolValue", true);
    }

    myClass _myClass = null;
    pubic UserContol2(myClass class)
    {
      _myClass = class;
      textBox2.DataBindings.Add("Text", _myClass, "TextString", true);
      numericUpdDown2.DataBindings.Add("Text", _myClass, "IntValue", true);
      checkBox2.DataBindings.Add("Text", _myClass, "boolValue", true);
    }
    2010年3月16日 上午 02:22

解答

  • 1.  兩個使用者控制項既然是一樣的, 應該只要建一個類別就好了
    2.  我是這樣做的
      (1) myClass
        public class myClass

        {
            private String _TxtString;
            public String TxtString
            {
                get { return _TxtString; }
                set { _TxtString = value; }
            }
            private Decimal _Nud;
            public Decimal Nud
            {
                get { return _Nud; }
                set { _Nud = value; }

            }
            private Boolean _Chk;
            public Boolean Chk
            {
                get { return _Chk; }
                set { _Chk = value; }
            }
        
        }
    (2) UserControl1
     public partial class UserControl1 : UserControl

        {

            private myClass _myObj;
            public UserControl1(myClass myObj)
            {
                _myObj = myObj;
                InitializeComponent();
                Change();             
            }
            private void Change()
            {
                textBox1.DataBindings.Add("Text", _myObj, "TxtString" );
                numericUpDown1.DataBindings.Add("Value", _myObj, "Nud");
                checkBox1.DataBindings.Add("Checked", _myObj, "Chk");
            }        
        }
    (3) Form1
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                myClass myObj = new myClass();
                UserControl1 U1 = new UserControl1(myObj);
                UserControl1 U2 = new UserControl1(myObj);
                U1.Location =new Point (0,0);
                U2.Location = new Point(250, 250);
                this.Controls.Add(U1);
                this.Controls.Add(U2);
            }
        }
    MSDN 文件庫很重要
    問題本身越具體, 越容易得到大家的回應
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    • 已標示為解答 Howard_cmit 2010年3月17日 上午 02:15
    2010年3月16日 上午 03:57
    版主

所有回覆

  • 我換個方式可以達到我想要的結果。
    以下是我變通的作法。

    public class myClass
    {
      //改成利用TexBox,在UserControl1變更textBox1.Text時,也變更此值的Text,則UserControl2中的textBox2.Text就會跟著變了。
      public TextBox TextString = new TextBox();
     
      public int IntValue
      {
         get;
         set;
      }
      public bool boolValue
      {
         get;
         set;
      }
    }

    myClass _myClass = null;
    pubic UserContol1(myClass class)
    {
      _myClass = class;
      textBox1.DataBindings.Add("Text", _myClass.TextString, "Text", true);
      numericUpdDown1.DataBindings.Add("Text", _myClass, "IntValue", true);
      checkBox1.DataBindings.Add("Text", _myClass, "boolValue", true);
    }

    myClass _myClass = null;
    pubic UserContol2(myClass class)
    {
      _myClass = class;
      textBox2.DataBindings.Add("Text", _myClass.TextString, "Text", true);
      numericUpdDown2.DataBindings.Add("Text", _myClass, "IntValue", true);
      checkBox2.DataBindings.Add("Text", _myClass, "boolValue", true);
    }
    2010年3月16日 上午 02:52
  • 1.  兩個使用者控制項既然是一樣的, 應該只要建一個類別就好了
    2.  我是這樣做的
      (1) myClass
        public class myClass

        {
            private String _TxtString;
            public String TxtString
            {
                get { return _TxtString; }
                set { _TxtString = value; }
            }
            private Decimal _Nud;
            public Decimal Nud
            {
                get { return _Nud; }
                set { _Nud = value; }

            }
            private Boolean _Chk;
            public Boolean Chk
            {
                get { return _Chk; }
                set { _Chk = value; }
            }
        
        }
    (2) UserControl1
     public partial class UserControl1 : UserControl

        {

            private myClass _myObj;
            public UserControl1(myClass myObj)
            {
                _myObj = myObj;
                InitializeComponent();
                Change();             
            }
            private void Change()
            {
                textBox1.DataBindings.Add("Text", _myObj, "TxtString" );
                numericUpDown1.DataBindings.Add("Value", _myObj, "Nud");
                checkBox1.DataBindings.Add("Checked", _myObj, "Chk");
            }        
        }
    (3) Form1
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                myClass myObj = new myClass();
                UserControl1 U1 = new UserControl1(myObj);
                UserControl1 U2 = new UserControl1(myObj);
                U1.Location =new Point (0,0);
                U2.Location = new Point(250, 250);
                this.Controls.Add(U1);
                this.Controls.Add(U2);
            }
        }
    MSDN 文件庫很重要
    問題本身越具體, 越容易得到大家的回應
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    • 已標示為解答 Howard_cmit 2010年3月17日 上午 02:15
    2010年3月16日 上午 03:57
    版主
  • 你的方向錯了.
    做DataBinding.他的來源物件好像要實作IDataBinding介面.
    像這種二個物件之間物件溝通要實作一些介面.
    像IPropertyChanged.這樣才有辦法一個物件的某個屬性值有改變會發出事件叫其他的控制項更新畫面.
    像ISelected.這樣你才有辦法在選某一個List的某個Item時去告訴其他的控件我選哪個值.

    上面的介面名稱只是我的映像.實際的名稱你要去看MSDN.

    每一種技術如WindowsForm,ASP.NET 都有資料處理的技術文章.
    你從頭看到尾你才知道他背後的動作.

    2010年3月16日 上午 04:02
  • 加入到ControlBindingsCollection集合中的物件並不需要先實作任何特別的Interface.
    而且.NET中好像也沒有 IDataBinding Interface.
    我所知道的是如果控制項要能進行資料繫結必須要實作 IBindableComponent Interface, 凡是控制項類別具備DataBindings與BindingContext屬性的就是有實作這個介面.

    MSDN 文件庫很重要
    問題本身越具體, 越容易得到大家的回應
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    2010年3月16日 上午 04:22
    版主
  • 謝謝 Bill Chung <abbr class="affil"> 的回覆。

    </abbr>
    這兩個UserControl並不是完全一樣的。只是某些資料需要是一致的。
    2010年3月16日 上午 05:46
  • 關於好說您提到的,我記得我有看到過。
    應該是INotifyPropertyChange這個Interface。msdn有範例。
    不過我不想弄到那麼複雜,所以想找個容易一點的方式。
    2010年3月16日 上午 05:48
  • UseControl不一樣沒關係, 道理上還是一樣的. 就是myClass中宣告屬性時也要宣告其相對應的變數.
    然後兩個或數個UserControl的DataBindings屬性指向的資料來源物件是同一個. 這樣應該是沒問題的.
    MSDN 文件庫很重要
    問題本身越具體, 越容易得到大家的回應
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    2010年3月16日 上午 05:49
    版主
  • 謝謝Bill Chung
    我原先的概念也是跟您一樣的。
    只是在我的程式碼中,只有Text那項,在兩個UserControl中沒有一致變更,
    所以我覺得很奇怪。
    但我另寫了一個簡單的測式,方式跟您所說的相同,作動就正確了。
    所以可能是我程式有什麼問題吧。
    總之這個方式是正確可行的。謝謝。
    2010年3月17日 上午 02:14
  • 經過測試,我發現造以下的問題。我把它寫出來。給以後的人參考

    Bill Chung的作法是正確的。
    但前題是,使用者必需在介面上變更,才會一致變更。
    例如:使用者必需點TextBox,輸入文字完成後,需點其它元件,就是要有Leave的事件發生(按Enter是沒用的),則另一個usercontrol上的TextBox才變更。

    所以若你TextBox的內容是用程式的方式去變更,則這個方式就會失效。
    例如:你有的按鈕去變更TextBox的文字,則這個方式就會沒有作用。此時可以參考我的作法。改用TextBox。見我的回覆。


    以上是我測試的結果。不正確請指教。謝謝
    2010年3月17日 上午 02:31
  • 經過測試,我發現造以下的問題。我把它寫出來。給以後的人參考

    Bill Chung的作法是正確的。
    但前題是,使用者必需在介面上變更,才會一致變更。
    例如:使用者必需點TextBox,輸入文字完成後,需點其它元件,就是要有Leave的事件發生(按Enter是沒用的),則另一個usercontrol上的TextBox才變更。

    所以若你TextBox的內容是用程式的方式去變更,則這個方式就會失效。
    例如:你有的按鈕去變更TextBox的文字,則這個方式就會沒有作用。此時可以參考我的作法。改用TextBox。見我的回覆。


    以上是我測試的結果。不正確請指教。謝謝
    Hi,
    跟我的觀念有所出入,提出來討論一下
    我是認為變更這個動作是在Validated事件作的
    如果不Leave也是可以
    呼叫觸發Validate即可

    而用程式碼去變更的話
    要用事件介面那邊才能偵測的到
    像是你上面提到的INotifyPropertyChange介面
    或是自行撰寫XXXChanged與XXXChanging事件

    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年3月17日 上午 04:31
  • 蹂躪一說我倒想起來,  我們之前被這問題困擾過.
    可以參考
    http://social.msdn.microsoft.com/Forums/zh-TW/232/thread/579f6bbf-5e43-4234-a930-b42c35d5be4c
    MSDN 文件庫很重要
    問題本身越具體, 越容易得到大家的回應
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    2010年3月17日 上午 04:43
    版主