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
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
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
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 🙂
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
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?
**:::
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.