2010-10-21 47 views
3

我想更好地瞭解數據綁定如何在.net中工作。我檢查this文章,我想出了這個代碼:C#中的數據綁定問題

public partial class Form1 : Form//, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler MyTextChanged; 

    [System.ComponentModel.Bindable(true)] 
    public string MyText 
    { 
     get { return textBox1.Text; } 
     set 
     { 
      textBox1.Text = value; 
      if (MyTextChanged != null) 
       MyTextChanged(this, new PropertyChangedEventArgs("MyText")); 
     } 
    } 

    MyClass myClass { get; set; } 

    public Form1() 
    { 
     InitializeComponent(); 
     myClass = new MyClass(); 
     Binding binding = new Binding("MyText", myClass, "Dic"); 
     binding.Parse += new ConvertEventHandler(binding_Parse); 
     binding.Format += new ConvertEventHandler(binding_Format); 
     DataBindings.Add(binding); 
     myClass.AddStuff("uno", "UNO"); 
    } 

    void OnMyTextChanged(PropertyChangedEventArgs e) 
    { 
     if (MyTextChanged != null) MyTextChanged(this, e); 
    } 

    void binding_Format(object sender, ConvertEventArgs e) 
    { 
     if (e.Value is Dictionary<string, string>) 
     { 
      Dictionary<string, string> source = (Dictionary<string, string>)e.Value; 
      e.Value = source.Count.ToString(); 
     } 
    } 

    void binding_Parse(object sender, ConvertEventArgs e) 
    { 
     MessageBox.Show(e.DesiredType.ToString()); 
    } 

    private void changemyClassButton_Click(object sender, EventArgs e) 
    { 
     myClass.AddStuff(myClass.Dic.Count.ToString(), "'" + myClass.Dic.Count.ToString() + "'"); 
    } 

    private void changeMyTextButton_Click(object sender, EventArgs e) 
    { 
     MyText = "1234"; 
    } 
} 

public class MyClass : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public Dictionary<string, string> Dic { get; set; } 

    public MyClass() 
    { 
     Dic = new Dictionary<string, string>(); 
    } 

    public void AddStuff(string key, string value) 
    { 
     Dic.Add(key, value); 
     if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Dic")); 
    } 
} 

我試圖綁定MyTextmyClass。問題是功能binding_Parse從未被調用。我知道我可以將textBox1.Text直接綁定到myClass,或者可能有其他可能的方法來做我想做的事情,但這只是一種實踐;我試圖理解更好的數據綁定。所以我想將一個自定義對象綁定到一個自定義屬性,這樣我就可以從頭到尾看到這個過程。自定義對象是myClass,自定義屬性是MyText。我嘗試了各種各樣的變體,例如執行INotifyPropertyChanged,但我無法調用binding_Parse(我希望在撥打changeMyTextButton_Click時調用它)。我錯過了什麼嗎?

編輯: 說得簡單:我想寫一個屬性string MyText用戶控件,然後用戶可以綁定到別的東西,以同樣的方式,你可以一個TextBoxText屬性綁定到別的東西。所以我不想將一個控件的屬性綁定到一個對象,我想用一個屬性編寫一個控件,然後用戶可以綁定到一個對象。

+0

你打算做什麼?用MyText屬性更新文本框內容?或強制binding_parse被執行? – 2010-10-21 20:27:01

+0

我想將'MyText'綁定到'myClass.Dic',這樣每當'MyText'發生變化時'myClass.Dic'發生變化(我想''binding'調用''開始調用,因爲我會在其中設置'MyText'的新值),並且每當'myClass.Dic'改變時,'MyText'改變(這已經有效)。當myClass.Dic沒有特殊原因改變時,我選擇將MyText設置爲myClass.Dic.Count.ToString()。我只是想看到一個反映在另一個上的任何變化。我找到了[這篇] [1]文章,但它是針對糧食計劃署的。我無法找到一個Windows窗體。 [1]:http://msdn.microsoft.com/en-us/library/ms752347.aspx – Juan 2010-10-21 20:39:50

+0

另一個例子是將'string str1'綁定到'string str2',以便每當'str1'發生變化時, str2'被設置爲'str1',每當'str2'改變時,'str1'被設置爲'str2'。全部通過使用標準的.net數據綁定。這將迫使我使用Format和Parse,並且我終於可以看到整個數據綁定週期是如何工作的。 – Juan 2010-10-21 20:44:29

回答

2

好的我想通了,以防萬一任何人有同樣的問題。我必須創建一個名爲MyTextChanged的事件處理程序,以讓Binding知道MyText正在更改,並將BindingDataSourceUpdateMode屬性設置爲OnPropertyChanged。使用這個簡單的原則,我可以將屏幕上的一個像素綁定到宇宙的其他部分:)。這裏是代碼:

public partial class Form1 : Form 
{ 
    public event EventHandler MyTextChanged; 

    [Bindable(true)] 
    public string MyText 
    { 
     get { return textBox1.Text; } 
     set 
     { 
      if (textBox1.Text != value) 
      { 
       textBox1.Text = value; 
       OnMyTextChanged(); 
      } 
     } 
    } 

    MyClass myClass { get; set; } 

    public Form1() 
    { 
     InitializeComponent(); 
     myClass = new MyClass(); 
     Binding binding = new Binding("MyText", myClass, "Dic"); 
     binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged; 
     binding.Parse += new ConvertEventHandler(binding_Parse); 
     binding.Format += new ConvertEventHandler(binding_Format); 
     DataBindings.Add(binding); 
     myClass.AddStuff("uno", "UNO"); 
    } 

    void OnMyTextChanged() 
    { 
     if (MyTextChanged != null) MyTextChanged(this, EventArgs.Empty); 
    } 

    void binding_Format(object sender, ConvertEventArgs e) 
    { 
     if (e.Value is Dictionary<string, string>) 
     { 
      Dictionary<string, string> source = (Dictionary<string, string>)e.Value; 
      e.Value = source.Count.ToString(); 
     } 
    } 

    void binding_Parse(object sender, ConvertEventArgs e) 
    { 
     MessageBox.Show(e.DesiredType.ToString()); 

    } 

    private void changemyClassButton_Click(object sender, EventArgs e) 
    { 
     myClass.AddStuff(myClass.Dic.Count.ToString(), "'" + myClass.Dic.Count.ToString() + "'"); 
    } 

    private void changeMyTextButton_Click(object sender, EventArgs e) 
    { 
     MyText = "1234"; 
    } 
} 

public class MyClass : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public Dictionary<string, string> Dic { get; set; } 

    public MyClass() 
    { 
     Dic = new Dictionary<string, string>(); 
    } 

    public void AddStuff(string key, string value) 
    { 
     Dic.Add(key, value); 
     if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Dic")); 
    } 
} 
+1

我仍然不明白的是爲什麼這不會造成無限遞歸。我想有一些內部機制可以防止這種情況發生。 – Juan 2010-10-22 06:34:59

1

也許這會幫助你,理解什麼時候執行Parse事件。

要查看binding_Parse工作看看這個例子:

public partial class Form1 : Form 
{ 

    public MyClass myClass { get; set; } 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     myClass = new MyClass(); 
     myClass.AddStuff("uno", "UNO"); 

     Binding b = new Binding("Text", myClass, "Dic"); 
     b.Parse += new ConvertEventHandler(b_Parse); 
     b.Format += new ConvertEventHandler(b_Format); 
     textBox1.DataBindings.Add(b); 
    } 

    void b_Format(object sender, ConvertEventArgs e) 
    { 
     e.Value = (e.Value as Dictionary<string, string>)["uno"].ToString(); 
     textBox1.Text = e.Value.ToString(); 
    } 

    void b_Parse(object sender, ConvertEventArgs e) 
    { 
     MessageBox.Show("This is executed when you lost focus\n\nI'm parsing your entered text: " + e.Value); 
    } 


} 

你只需要調試。點擊按鈕,並注意格式事件首先被調用。 然後如果你手動改變textbox1.Text的值,當你再次點擊該按鈕時,會出現焦點丟失,然後Parse事件將被執行。

要創建您的自定義控件,還請檢查this site

+0

請參閱我的編輯。我對這種混亂表示歉意。希望你仍然可以幫助我。 – Juan 2010-10-21 20:55:56

+0

好的,你看到我告訴你的網站嗎? – 2010-10-21 22:39:47

+0

我做了,但是我找不到任何關於綁定屬性的東西;他們改用事件。 – Juan 2010-10-22 03:43:19