Laden...

DataGridBoolColum änderung sofort übernehmen

Erstellt von bierstuebl vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.307 Views
B
bierstuebl Themenstarter:in
14 Beiträge seit 2006
vor 17 Jahren
DataGridBoolColum änderung sofort übernehmen

Hallo zusammen,

dieses Datagrid (ich muss mit VS 2003 arbeiten) treibt mich noch zum Wahnsinn 🙂

Folgendes Problem (das doch eigentlich soziemliche jeder schonmal gehabt haben müsste):

Ich habe eine DataTable an eine DataGrid angebunden. Die erste Spalte besteht aus Bool-Werten, ich benutze also DataGridBoolColumn als ColumnStyle zur Anzeige. Das Verhalten des DataGrids ist aber völlig Benutzerunfreundlich dabei, da

1: Zum Ändern der Checkbox die Zeile erst einmal angeklickt werden muss um sie in den Edit-Modus zu versetzen und dann ein zweites Mal geklickt werden muss, um ein Häkchen zu setzen/zu entfernen.

Mit Verhalten 1: kann ich zur Not noch Leben. Wirklich schlimm ist folgendes:

2: Wir ein Häkchen gesetzt oder entfernt, so schlägt diese Änderung erst auf den Datatable duch, wenn der Commit-Event ausgelöst wurde (wer macht das eigentlich? Das Datagrid?), der die Methode Commit(..) der DataGridBoolColumn aufruft. Das passiert jedoch nur, wenn im DataGrid in eine andere Zelle geklickt wird. Wählt ein Benutzer beispielsweise eine Zeile durch ein Häkchen an und ruft danach direkt einen Menüpunkt auf oder ähnliches, so wird kein Commit auf die Datatable durchgeführt, Datatable und Datagrid enthalten nicht die gleichen Daten! Für den Benutzer natürlich völlig unverständlich, er sieht, das die Zeile z.B. angehakt ist, wenn von mir der Datatable dann aber ausgewertet wird, ist dort die entsprechende Spalte eben auf false! Ich kann doch kein Programm schreiben, bei dem der Benutzer immer erstmal woanders in der Tabelle hinklicken muss. Das Comit muss doch durchgeführt werden wie z.B. bei Excel auch - sobal irgendwo anders als in die Zelle geklickt wurde, also auch auf einen Menüpunkt, einen Button, den Hintergrund, was auch immer!!!

DataGridBoolColumn abzuleiten und eben im Changed-Event ein Commit auszulösen wäre ja völlig falsch, da Commit ja von aussen aufgerufen werden muss, da dann ja auch der Edit-Mode verlassen werden soll etc.

Wäre über Hilfe zu diesem Thema sehr dankbar.

Der Bierstuebl

849 Beiträge seit 2006
vor 17 Jahren

Hallo,

ist vielleicht nicht die schönste möglichkeit... aber ich hab bei solchen Sachen immer das Cell klick event abgfangen, den haken darin gesetzt / entfernt und dann auf die BindingSource endedit() aufgerufen. Das funktioniert auf alle fälle.

Gruss

B
bierstuebl Themenstarter:in
14 Beiträge seit 2006
vor 17 Jahren

Hmm, ist sicherlich ne Möglichkeit für die Checkboxen, wenn auch nicht gerade schön 🙂
Werd ich zur Not benutzen, Danke.

Ich brauch das Ganze aber im nächsten Schritt wahrscheinlich auch für Textboxen etc., d.h. wenn der Benutzer irgendwo anders hinklickt (auch ausserhalb der Tabelle), dann muss der momentan enthaltene Text committed werden. Im Prinzip ists ja nur sowas wie ein Fokuswechsel - die Tabellenzelle behält aber eben dummerweise den Fokus, egal ob ein Menü oder so angewählt wird oder nicht 😦

Da muss es doch irgendwie eine offizielle Möglichkeit geben, oder?

Der Bierstuebl

849 Beiträge seit 2006
vor 17 Jahren

Hmm, eventuell mouseleave?

B
bierstuebl Themenstarter:in
14 Beiträge seit 2006
vor 17 Jahren

mouseleave ist mir dann doch zuviel des Guten 🙂 Aber danke für den Vorschlag.

Ich habe inzwischen rausgefunden, dass das Problem hauptsächlich im Zusammenhang mit Menüs auftritt. Wähle ich zum Beispiel direkt nach dem Setzen eines Häkchen eine Combobox woanders auf der Form an, so verliert die Zelle den Focus und Comitted. Klicke ich statt auf die ComboBox auf einen Menüpunk passiert gar nix.

Doch sellbst mit dem Klicken auf die Kombobox stimmt nicht alles - so wies aussieht ist die Zelle mit der Checkbox irgendwie doch noch im Editmodus oder so, denn wenn man sie nun wieder anklicke braucht man nicht mehr 2 Klicks wie sonst (einen um die Zelle in den Edit-Modus zu versetzen und einen um ein Häkchen zu machen) sondern der Haken wird direkt beim ersten Klick in die Zelle gesetzt bzw. entfernt. Ich hab langsam das Gefühl, diese ganze DataGrid Sache ist ziemlich buggy 😦

Die Frage ist nun: Warum funktionert der Commit beim Wechsel zu einer Combobox, nicht aber beim Wechsel zu einem Menüpunkt und wie bekomme ich das so hin, dass das Verhalten bei einem Menüpunkt eben gleich ist wie bei der ComboBox.

Fragen über Fragen 🙂

M
104 Beiträge seit 2005
vor 17 Jahren

Original von bierstuebl
Warum funktionert der Commit beim Wechsel zu einer Combobox, nicht aber beim Wechsel zu einem Menüpunkt und wie bekomme ich das so hin, dass das Verhalten bei einem Menüpunkt eben gleich ist wie bei der ComboBox.

Hallo bierstuebl,

dieses Problem hat mir auch einiges an Kopfschmerzen bereitet. Mit folgendem Workaround habe ich dies bei mir gelöst:

Wenn auf das Menü bzw. den BindingNavigator geklickt wird, prüfe ich, ob ein anderes Control den Focus hat, verschiebe den Focus ein Control nach vorn und dann setze ich ihn wieder auf das ursprüngliche Control. Dadurch erreiche ich, dass auch das Control, welches aktuell den Focus hat, validiert wird.

Das ist zwar nicht der Weisheit letzter Schluss, aber ich habe mir nicht anders helfen können. Auch eine Internetrecherche hat keine akzeptablere Lösung gebracht. Sind wir eigentlich die Einzigen, die ein solches Problem haben?

private void OnBindingNavigatorClick(object sender, EventArgs e) {
   ChangeFocus();
}

private void OnMainMenuStripClick(object sender, EventArgs e) {
   ChangeFocus();
}

private void ChangeFocus() {
   if (detailsTabControl.ContainsFocus || commonDataGroupBox.ContainsFocus) {
      foreach (Control control in detailsTabControl.Controls) {
         if (control.HasChildren) {
            foreach (Control cntrl in SpecialFormFunctions.GetControls(control)) {
               if (cntrl.Focused) {
                  // Control, das aktuell den Focus hat merken
                  Control focusedControl = cntrl;
                  // Focus auf das nächste Control setzen -> focusedControl wird validiert
                  SelectNextControl(cntrl, true, true, true, true);
                  // Focus zurück auf das ursprüngliche Control setzen.
                  focusedControl.Focus();
               }
            }
         }
      }
   }
}

Evtl. kann ja jemand aus der Community helfen, eine bessere Lösung zu finden.

Gruß
Morpheus

B
1.529 Beiträge seit 2006
vor 17 Jahren

Was ist denn mit Invalidated?
Zeigt das Ereignis nicht an, dass sich Teile des GridViews neu darstellen müssen, weil sie geändert wurden?
Oder halt Validated?

D
1 Beiträge seit 2007
vor 17 Jahren

**:::

Hallo,

ich habe auch das problem gehabt, das ich einen Auto-Commit für meine Controls wollte,
sprich:
Sobald der Benutzer in einer CheckBox clickt, in einerm TextFeld etwas ändert, und vor allem in einerm DropDown etwas anderes Auswählt, wollte ich, dass diese Änderung sofort an die DataSource commited wird.

Die Lösungsansätze die ich hier gelesen habe sind leider nur Workarounds.
Hier die Gute Nachricht: Diese Braucht es aber garnicht 🙂

Mann kan beim DataBinding auch mit angeben, dass Änderungen sofort commited werden sollten.
Das Stichwort heisst "DataSourceUpdateMode.OnPropertyChanged".

Also so zum beispiel:

myTextBox.DataBindings.Add("Value", this.myBindingSource, "MyProperty", DataSourceUpdateMode.OnPropertyChanged);

Und schon wir alles sofrt an die DataSource commited.

BTW: Ich verwende .NET 2.0. (Ich weis nicht ob es das in 1.0 auch schon gibt)

Hoffe ich konnte jemand damit weiterhelfen.