2010-10-28 4 views
4
public partial class Form1 : Form 
{ 
    MyClass myClass = new MyClass("one", "two"); 

    public Form1() 
    { 
     InitializeComponent(); 
     textBox1.DataBindings.Add("Text", myClass, "Text1", false, DataSourceUpdateMode.Never); 
     textBox2.DataBindings.Add("Text", myClass, "Text2", false, DataSourceUpdateMode.Never); 
    } 

    private void saveButton_Click(object sender, EventArgs e) 
    { 
     myClass.Text1 = textBox1.Text; 
     myClass.Text2 = textBox2.Text; 
     //textBox1.DataBindings["Text"].WriteValue(); 
     //textBox2.DataBindings["Text"].WriteValue(); 
    } 
} 

public class MyClass : INotifyPropertyChanged 
{ 
    private string _Text1; 
    private string _Text2; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public string Text1 
    { 
     get { return _Text1; } 
     set { _Text1 = value; OnPropertyChanged(new PropertyChangedEventArgs("Text1")); } 
    } 

    public string Text2 
    { 
     get { return _Text2; } 
     set { _Text2 = value; OnPropertyChanged(new PropertyChangedEventArgs("Text2")); } 
    } 

    public MyClass(string text1, string text2) 
    { 
     Text1 = text1; 
     Text2 = text2; 
    } 

    protected void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) PropertyChanged(this, e); 
    } 
} 

Je pense est assez clair ce que j'essaie d'atteindre. Je veux que mon formulaire enregistre les modifications apportées dans mes deux TextBox es à myClass. Mais chaque fois que j'appuie sur le bouton Enregistrer après avoir édité les deux zones de texte, et saveButton_Click est invoqué, le deuxième textBox2Text retourne au texte original ("deux"). J'ai essayé d'utiliser la fonction WriteValueBinding mais la même chose se produit. Utiliser .net 4.0.Problème avec DataBindings, expliquer s'il vous plaît

Modifier Merci pour vos réponses, mais je n'ai pas besoin de solutions de contournement. Je peux les trouver moi-même. J'ai juste besoin de comprendre un peu mieux comment la liaison fonctionne. Je voudrais comprendre pourquoi cela se passe-t-il?

Répondre

5

Apparemment, la mise à jour d'une valeur sur la source de données provoquera la mise à jour de toutes les liaisons. Ceci explique le comportement (le réglage myClass.Text1 provoque la mise à jour de textBox2 avec la valeur actuelle de myClass.Text2). Malheureusement, les quelques articles que j'ai pu trouver à peu près ont simplement dit: «Voilà comment ça fonctionne».

Une façon de gérer cela est de créer un BindingSource, définir BindingSource.DataSource = myClass, puis lier vos TextBoxes au BindingSource.

BindingSource soulève ListChanged événements si la source de données sous-jacente est une liste et des éléments sont ajoutés, supprimés, etc., ou si les propriétés changent DataSource. Vous pouvez supprimer ces événements en définissant BindingSource.RaiseListChangedEvents sur false, ce qui vous permet de définir plusieurs propriétés sur myClass sans liaison de données mettant à jour les contrôles liés.

public partial class Form1 : Form 
{ 
    MyClass myClass = new MyClass("one", "two"); 
    BindingSource bindingSource = new BindingSource(); 

    public Form1() 
    { 
     InitializeComponent(); 

     bindingSource.DataSource = myClass; 

     textBox1.DataBindings.Add("Text", bindingSource, "Text1", true, DataSourceUpdateMode.Never); 
     textBox2.DataBindings.Add("Text", bindingSource, "Text2", true, DataSourceUpdateMode.Never);     
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     bindingSource.RaiseListChangedEvents = false; 
     myClass.Text1 = textBox1.Text; 
     myClass.Text2 = textBox2.Text; 
     bindingSource.RaiseListChangedEvents = true; 
    } 
} 

HTH

+0

Cela a fonctionné. Mais je ne comprends pas pourquoi si mes propriétés ne font pas partie d'une liste. – Juan

+0

@jsoldi, j'ai édité ma réponse pour inclure le fait que 'ListChanged' est également levé quand les propriétés' DataSource' changent. –

1

Vous devez modifier la manière dont vous effectuez la liaison de données. Essaye ça.

MyClass myClass = new MyClass("one", "two"); 

public Form1() 
{ 
    InitializeComponent(); 
    textBox1.DataBindings.Add("Text", myClass, "Text1", false, DataSourceUpdateMode.OnPropertyChanged); 
    textBox2.DataBindings.Add("Text", myClass, "Text2", false, DataSourceUpdateMode.OnPropertyChanged); 
} 

private void saveButton_Click(object sender, EventArgs e) 
{ 
    // your object should already have new text values entered. 
    // Save your object! 

    //myClass.Text1 = textBox1.Text; 
    //myClass.Text2 = textBox2.Text; 
    //textBox1.DataBindings["Text"].WriteValue(); 
    //textBox2.DataBindings["Text"].WriteValue(); 
} 

La clé est le DataSourceUpdateMode, cela permettra la propriété de texte de la zone de texte en cascade dans votre objet personnalisé à chaque fois que les changements de propriété. J'espère que ça aide.

[Modifier]

Je crois que ce que vous devez faire pour obtenir ce que vous demandez est ceci: TextBox1.DataBindings[0].ControlUpdateMode = ControlUpdateMode.Never Cette link devrait fournir des informations supplémentaires.

+1

Mais je ne veux pas que les données soient enregistrées lorsque les modifications '' Text' de TextBox', je veux que ça change lorsque le bouton d'enregistrement est enfoncé. Comment puis je faire ça? "DataSourceUpdateMode.Never" n'est-il pas associé à "WriteValue()" pour réaliser ce type de fonctionnalité? – Juan

+0

N'utilisez pas de liaisons de données. Affectez manuellement les valeurs de texte dans le constructeur de formulaires aux zones de texte, comme ceci: 'textBox1.Text = myClass.Text1;' – James

+0

@jsoldi - n'utilisez pas de liaison de données pour ces valeurs - définissez les valeurs dans l'événement saveButton_Click. C'est la raison d'être de la liaison de données: elle lie les propriétés des instances de contrôle aux propriétés de l'objet de données. – JeremyDWill