Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Datenbing an Control ohne automatisches Update
ymarviny
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

Datenbing an Control ohne automatisches Update

beantworten | zitieren | melden

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());

2. 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);

3. 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
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von ymarviny am .
Attachments
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.976

beantworten | zitieren | melden

Damit Databinding funktioniert ist INotjfyPropertyChanged wichtig.

Und wegen Cancel, IEditableObject ist nicht sonderlich schwer zu implementieren.
private Nachricht | Beiträge des Benutzers
Florian Reischl
myCSharp.de - Experte

Avatar #avatar-2880.jpg


Dabei seit:
Beiträge: 1.564
Herkunft: München

beantworten | zitieren | melden

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

Eingeschränkt "ja" (bei immutable Typen). Lustig kann das mit komplexen Typen werden...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Florian Reischl am .
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ß.
private Nachricht | Beiträge des Benutzers
ymarviny
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

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
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von ymarviny am .
private Nachricht | Beiträge des Benutzers