Laden...

DataGridView.OnCellValidating e.FormattedValue enthält nicht den aktuellen Wert

Erstellt von ChrisProg vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.981 Views
ChrisProg Themenstarter:in
174 Beiträge seit 2009
vor 10 Jahren
DataGridView.OnCellValidating e.FormattedValue enthält nicht den aktuellen Wert

Hallo zusammen,

ich habe für ein DataGridView folgende Klasse geschrieben:

        protected override void OnCellValidating(DataGridViewCellValidatingEventArgs e)
        {
            ///<summary>
            /// Die folgende Prozedur überprüft, ob das Feld ein Datumsfeld ist,
            /// wenn ja und die Jahreszahl fehlt, dann wird diese automatisch hinzugefügt.
            /// Sollte das Datum in diesem Feld ungültig sein, wird das Verlassen des 
            /// Feldes verweigert und eine ToolTip mit einer entsprechenden Meldung
            /// und ein ErrorEvent für das Feld ausgegeben
            /// </summary>
            if (CurrentCell.Value != null)
            {
                if (CurrentCell.Value.GetType() == typeof(DateTime))
                {
                    string text = CurrentCell.EditedFormattedValue.ToString();
                    if (text.Length == 6 && text.Substring(5, 1) == ".")
                    {
                        text += DateTime.Now.Year.ToString();
                        //SelectionStart = Text.Length;
                        //SelectionLength = 1;
                    }
                    try
                    {
                        DateTime dateValue = DateTime.Parse(text.ToString().Trim());
                        CurrentCell.Value = dateValue.ToString();

                        if (CurrentCell.IsInEditMode)
                        {
                            (CurrentCell.DataGridView.DataSource as BindingSource).EndEdit();
                            CurrentCell.DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
                        }
                        
                        if (mit_ToolTip_bei_Fehler)
                        { ToolTip_uDGV.Hide(((System.Windows.Forms.DataGridView)(this))); }

                        CurrentCell.ErrorText = String.Empty;
                        e.Cancel = false;

                        base.OnCellValidating(e);
                    }
                    catch (Exception ex)
                    {
                        // ist das rote Ausrufungszeichen, das einen Datenfehler markiert
                        CurrentCell.ErrorText = text.Trim() + " ist kein gültiges Datum";

                        if (mit_ToolTip_bei_Fehler)
                        {
                            // Damit ToolTip.Show funktionieren kann, muß DataGridView.ShowCellToolTips auf false stehen
                            if (ShowCellToolTips) { ShowCellToolTips = false; }
                            // Position des Feldes ermitteln
                            var cellDisplayRect = GetCellDisplayRectangle(CurrentCell.ColumnIndex, CurrentCell.RowIndex, false);

                            ToolTip_uDGV.ToolTipTitle = "Datum nicht korrekt";
                            ToolTip_uDGV.Show(text.Trim() + " ist ungültig", this,
                                            cellDisplayRect.X + CurrentCell.Size.Width / 2,
                                            cellDisplayRect.Y + CurrentCell.Size.Height / 2, 1000);
                        }
                        e.Cancel = true;
                    }

                }
                else
                {
                    base.OnCellValidating(e);
                }
            }
        }

Das ganze funktioniert wunderbar, bis auf:
Nachdem CurrentCell.Value auf den neuen Wert gestetzt wurde, wird e.FormattedValue nicht upgedated 🙁

Beispiel: Ich verlasse die Zellel mit "02.05." dann wird "2013" an den Wert drangehängt.
CurrentCell.EditedFormattedValue ist korrekt, CurrentCell.FormattedValue auch, aber e.FormattedValue nicht (da steht weiterhin "02.05." drin)

Nun kann ich e.FormattedValue nicht direkt ändern, aber ich hätte erwartet, das mit


(CurrentCell.DataGridView.DataSource as BindingSource).EndEdit();
CurrentCell.DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);

oder


                            DateTime x_datum = DateTime.Parse(CurrentCell.Value.ToString());
                            CurrentCell.Value = DateTime.MinValue.ToShortDateString();
                            CurrentCell.Value = x_datum;

das ganze wieder "gerade rücken" könnte.
Aber leider nicht 😜

Weiss irgendjemand, wie man das lösen kann ?
Wie gesagt, es ist eine Klasse und die übergibt im Erfolgsfall an base.OnCellValidating(e) - u. da wird des öfteren nach e.FormattedValue gefragt ( wenn !IsCellDirty).
MfG ChrisProg

S
145 Beiträge seit 2013
vor 10 Jahren

Vielleicht hilfts dir ja was.

Du könntest mal probieren EditingControlShowing Ereignis des DataGridViews zu abonnieren.
Und wenn TextBox dort zum Beispiel Leave Ereignis dieser Textbox abonnieren und dort die Datumsprüfung machen.

Achtung beim abonnieren des EditingControlShowing es wird nicht jedesmal eine neue TextBox instanz erstellt, falls du Ereignisse dieser Textbox abonnieren willst.

Und für die Datumsformatierung könntest du dir ja mal DateTime.TryParseExcat anschauen, dort kannst du mehrere dir erlaubte formatierung einer Datumseingabe angeben und musst nicht selbst den string prüfen.

M
7 Beiträge seit 2012
vor 10 Jahren

Von: MSDN: DataGridViewCell.FormattedValue Property

Getting the value of this property calls the GetFormattedValue method to convert the cell value into an equivalent display value of the type indicated by the FormattedValueType property. This raises the DataGridView.CellFormatting event, which you can handle to customize the value conversion.

Hast du vielleicht "CellFormatting" überschrieben und verhinderst da den base-Aufruf?

ChrisProg Themenstarter:in
174 Beiträge seit 2009
vor 10 Jahren

Hallo zusammen,

nun da ich das Problem lösen konnte, hier der Weg:

@MatthiasDietschweiler - nein, ich habe den Wert nicht überschrieben
@Spyke - Du hast mich auf die richtige Spur gebracht:

ich habe "OnCellLeaving" abboniert.
Dort konnte ich leider auch nicht auf FormattedValue zugreifen, aber indem ich den neuen Wert nicht in CurrentCell.Value
sondern in ((((DataGridViewElement)(CurrentCell)).DataGridView).EditingControl).Text geschrieben habe, hat VS alles andere im Hintergrund gemacht 8)

Wichtig ist dabei auch noch, die Zeile

CurrentCell.Value = dateValue.ToString();

aus "OnCellValidating" zu entfernen.

MfG ChrisProg