Laden...

Datenbing an Control ohne automatisches Update

Erstellt von ymarviny vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.018 Views
Y
ymarviny Themenstarter:in
5 Beiträge seit 2009
vor 14 Jahren
Datenbing an Control ohne automatisches Update

Hallo zusammen,

ich habe ein Problem, was ich nicht schaffe zu lösen. Ich habe in einer extra DLL ein Form erstellt, welches mir die Optionen im Programm anzeigen soll die man dann verändern kann.

Dazu binde ich an das Control jeweils die entsprechenden Einstellungen


txtBackupPfad.DataBindings.Add("Text", setVars, "BackupPfad", false, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged);

Das Form mit dein einzelnen EInstellungen füge ich dann mit


    Panels.Add(new cOptGeneral());

dem Optionsform hinzu und erstelle dabei jeweils einen Menüeintrag für jedes neue Panel.

Jetzt kann ich die Werte ändern und wenn ich das Form verlasse sind die Werte auch in der Variable gesetzt. Jetzt wollte ich aber auch ein "Cancel" einbauen und dachte. wenn ich DataSourceUpdateMode auf Never setzte, kann ich über ReadValue bzw. WriteValue bestimmen ob die Variable gesetzt wird oder nicht.

Leider aber bleibt beim Updatemode "Never" alles leer bzw.ich bekomme es nichthin das der Wert im Steuerelement nicht gleich automatisch auf dem Wert der Datenbindung übertragen wird.

Ich habe schon mit "OnValidation", "OnPropertyChanged" und "Never" einiges probiert...

Anbei noch mal Code zum Verständis:

Im Hauptprogramm

  1. frmOptions.cs
    Zeigt die Einstellungen an. Hier werden nur die einzelnen Einstellungsübersichten hinzugefügt.

    Panels.Add(new cOptGeneral());
    Panels.Add(new cOptFolder());

  1. cOptFolder
    Für jede Einstellungsgruppe gibt es ein Control

            txtBackupPfad.DataBindings.Add("Text", setVars, "BackupPfad", false, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged);
            txtHistoryPfad.DataBindings.Add("Text", setVars, "HistoryPfad", false, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged);

  1. Eine extra DLL übernimmt die Anzeige und Aktualisierung. Hier wollte ich dann bei Canzel die Werte zurücksetzen

        private void ReloadValues(Control ctrl)
        {
            for (int i = 0; i < ctrl.Controls.Count; i++)
            {
                Control ctrl2 = ctrl.Controls[i];

                for (int l = 0; l < ctrl2.DataBindings.Count; l++)
                {
                    Binding bind = ctrl2.DataBindings[l];
                    bind.ReadValue();
                }

                ReloadValues(ctrl2);
            }
        }

Oder sollte man das ganz anders machen? Aber eine andere tolle Idee habe ich dafür noch nicht gefunden.

Gruß
Frank

5.299 Beiträge seit 2008
vor 14 Jahren

Ich hab mal versucht über DataSet.RejectChanges, oder BindingSource.CancelEdit() ein Canceln zu implementieren.
Hat alles nicht wirklich getaugt - ging so lala, verhielt sich dann aber bei mehrfachem Ändern und dann canceln komisch.
Ende vom Lied: Eine Cancel-fähige Eingabe hastenur, wennde auf einer _Kopie _der Daten arbeitest, und die entweder verfallen läßt, oder übernimmst.

Der frühe Apfel fängt den Wurm.

F
10.010 Beiträge seit 2004
vor 14 Jahren

Damit Databinding funktioniert ist INotjfyPropertyChanged wichtig.

Und wegen Cancel, IEditableObject ist nicht sonderlich schwer zu implementieren.

1.564 Beiträge seit 2007
vor 14 Jahren

Und wegen Cancel, IEditableObject ist nicht sonderlich schwer zu implementieren.

Eingeschränkt "ja" (bei immutable Typen). Lustig kann das mit komplexen Typen werden...

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

Y
ymarviny Themenstarter:in
5 Beiträge seit 2009
vor 14 Jahren

Danke für die Antworten. Ich habe mir mal INotjfyPropertyChanged in der MSDN angeschaut es dann aber dafür nicht verwendet. Habe mir das aber mal gemerkt, kann man sicherlich mal gebrauchen.

Nach den Hinweis von "Mr. Beem" 😉 habe ich folgende Lösung entwickelt:

Beim hinzufügen des Panels speicher ich mir die aktuellen Werte im TAG-Falg ab:


        private void InitPanelForControl(Control ctrl)
        {
            
            for (int i = 0; i < ctrl.Controls.Count; i++)
            {
                Control ctrl2 = ctrl.Controls[i];

                if (ctrl2.DataBindings.Count > 0)
                {
                    string propertyName = ctrl2.DataBindings[0].PropertyName;
                    switch(propertyName)
                    {
                        case "Text":
                            ctrl2.TextChanged += new System.EventHandler(ctrl2_TextChanged);
                            break;
                        case "Checked":
                            break;
                    }
                    ctrl2.Tag = ctrl2.GetType().InvokeMember(propertyName,  BindingFlags.GetProperty, null, ctrl2, null);
                }
                
                InitPanelForControl(ctrl2);
            }
        }

Wird nun ein Wert geändert und anschließend nicht Save/Apply sondern Cancel gedrückt, dann schreibe ich die Werte wieder zurück:


        private void ReloadValues(Control ctrl)
        {
            for (int i = 0; i < ctrl.Controls.Count; i++)
            {
                Control ctrl2 = ctrl.Controls[i];

                for (int l = 0; l < ctrl2.DataBindings.Count; l++)
                {
                    string propertyName = ctrl2.DataBindings[0].PropertyName;
                    ctrl2.GetType().InvokeMember(propertyName, System.Reflection.BindingFlags.SetProperty, null, ctrl2, new object[] { ctrl2.Tag });                                
                }

                ReloadValues(ctrl2);
            }
        }

Das geht zumindest. Danke für die Tipps.

Gruß
Frank