Ich habe den entsprechenden Passus zwar auch gelesen, aber ich verstehe nicht, was oder warum ich einen String "parsen" soll/muß - es bleibt doch ein String ?(
Er hat doch nur ein paar Leerstellen zur Formatierung hinzubekommen, aber es bleibt ein String.
Zu IBAN: natürlich weiß ich, das eine IBAN über die Prüfsumme definiert wird, aber ich weiß auch das sie in D immer 23 Stellen und international min 16 Stellen (Belgien) und max. 30 Stellen haben kann, das kann man ja auch schon vorher abprüfen.
den ValidatingType "typeof(string)" habe ich hier genommen, damit die Methode TypeValidationCompleted überhaupt durchlaufen wird.
Nur: bei diesem ValidatingType ist e.IsValidInput immer true, ganz gleich ob es jetzt 16 Stellen oder nur drei sind, deshalb mus ich wohl lt. MS einen benutzedefinierten Datentyp erstellen.
Ich finde einige Beispiel wie ich verschieden Felder zu einer Gruppe zusammenfügen kann, aber nirgendwo einen Hinweis, wie ich es schaffe, einen in Länge definierten String (alles andere prüft die Mask ja schon ...) zu erstellen - wenn das überhaupt geht.
Das wäre mit Sicherheit ja auch für die Überprüfung einer IBAN hilfreich ...
Mit dieser Herangehensweise habe ich doch nichts gewonnen ...
Ok, mit dem Installer könnte ich die Schlüssel anlegen, aber wenn ich den Counter hochsetzen will,
muß ich ja wieder schreibend zugreifen.
Würde ich das mit dem Counter außerhalb der Registry machen, dann könnte man ja wieder relativ leicht manipulieren.
Bei abschließenden der Lizensierung könnte man ja bewusst "als Admin" starten, um die Werte zu setzen, aber das Setzen des Counters muß unbemerkt passieren.
leider funktioniert die E-Mail-Benachrichtigung nicht , sonst hätte ich eher geantwortet...
Definitiv verweise ich auf das Manifest - siehe Anhang...
Im Ausgabeverzeichnis erscheint dann nach dem Kompilieren eine <Progname>.vshost.manifest mit genau den Einstellungen, wie ich sie in der app.manifest vorgenommen habe ...
Wenn ich, wie von Lars angeregt, eine Manifest-Datei entsprechend eingebunden und angepasst habe, wird beim Kompilieren trotzdem im Ausgabeverzeichnis eine Manifest-Datei generiert.
Aber lt. Projekteigenschaften soll sie doch eingebunden werden ???
Muß ich diese Manifest-Datei jetzt mit zum Kunden ausliefern, oder nicht ???
(das wäre ja fatal, da der Kunde sie dann ja ändern könnte ...)
kann mir irgendjemand sagen, was ich falsch mache ?(
Ausgangssituation:
Ich habe eine Tabelle, in der unter anderem die IBAN eingetragen ist.
Nun möchte ich die Anzeige formatiert in dem DataGridView angezeigt bekommen (## ## #### #### #### #### ##) ,
aber alle Versuche das zu erreichen führen zu keinem Ergebnis
Aber wenn ich einen neuen Datensatz (mit Hilfe der Navigationsleiste) erstelle, steht "Current" nicht auf dem neuen Datensatz, viel schlimmer noch, wenn ich mit dem o.g. Code das entsprechende Feld füllen will, springt die BindingSource in den neuen Datensatz (--> die Felder werden mit den Werten aus dem vorhandenen DS gefüllt) 8o
Wenn ich mir <Tabelle_BindingSource>.Current direkt nach der Neuerstellung (in bindingNavigatorAddNewItem_Click(object sender, EventArgs e)) anschaue, dann ist unter DataView zu sehen, das die BS eben nicht auf dem neuen DS steht, sondern immer noch auf dem "alten".
Laut MSDN sollte aber automatisch auf den neuen DS gewechselt werden
Was muß ich tun, um auch bei einem neuen DS das richtige Feld direkt zu füllen?
Ein <Tabelle_BindingSource>.EndEdit() brachte auch keine Besserung, da die BS ja auf einem falschen DS steht ...
eine Sache verstehe ich nach all meinen Tests jetzt aber nicht:
verwende ich Mask = "00/00/0000" dann ist MaskCompleted immer false außer wenn ein korrektes Datum eingeben wurde;
verwende ich Mask = "##/##/####" dann ist MaskCompleted immer true, egal, ob das Feld leer, das Datum gültig, ungültig oder unvollständig ist.
Somit ist diese Eigenschaft zur Überprüfung, ob das Feld leer ist überhaupt nicht zu gebrauchen X(
Lt. Fabian soll man ja
Zitat von Fabian
für so eine Abfrage bitte nicht die Maske direkt in der Abfrage verwenden
die Maske nicht direkt abfragen [also nicht so : (--> das funktioniert aber!)]
Jetzt meine Frage dazu:
natürlich weiß ich welches Feld dahinter liegt, da ich aber die Prozedur als Klasse benutzen will - kann man über die Eigenschaften die BindingSource der entsprechenden MaskedTextBox herausfinden, oder ist es gar möglich "Null" an die BindingSource durchzugeben ???
natürlich habe ich vorher (bevor ich diesen Threat erstellt habe) mit Hilfe des Debuggers die Werte überprüft ...
e.Cancel steht definitv auf false !!!
Auch ein zusätzliches Setzten "e.Cancel = false" hat an dem Verhalten nichts geändert...
Das ist ja gerade, was ich nicht verstehe: lt. Microsoft sollte nur bei e.Cancel = true der Focus auf der MaskedTextBox bleiben, aber er ist false !!!
Auch im nachfolgend ausgeführten Validating ist e.Cancel lt. Debugger false
es ist egal, ob ich
a) Mask = "00/00/0000" und die Abfrage nach MaskCompleted
oder
b) Mask = "##/##/####" und dei Abfrage nach MaskFull
mache, der Code funktioniert ja - die Schleife wird jeweils ohne die Überprüfung von
if (e.IsValidInput)...
korrekt durchgeführt.
Aber: trotzdem behält dieses Feld den Focus u. ich weiss nicht warum
Wenn die Cancel-Eigenschaft im TypeValidationCompleted-Ereignishandler auf true festgelegt ist, wird das Ereignis abgebrochen, und das MaskedTextBox-Steuerelement behält den Fokus, bis ein nachfolgendes Validating-Ereignis seine Version der CancelEventArgs.Cancel-Eigenschaft auf false zurücksetzt.
e.Cancel ist definitiv auf false u. trotzdem bleibt der Focus
Irgendwie habe ich da was wohl nicht richtig verstanden, oder ???
HIntergrund: ich möchte das beim Verlassen des Feldes das Datum auf Gültigkeit überprüft wird, wenn nicht, soll der Focus auf dem Feld bleiben; ist das Datumsfeld jedoch leer, so soll der Focus auch auf das nächste Feld gehen.
Aber genau das passiert nicht
Das gebundene Feld lässt aber NUll-Values zu ...
Was muß ich tun, damit die MaskedTextBox bei einem leeren Datum verlassen werden kann?
soweit ist es auch kein Problem.
Die Parameter sind in Crystal Reports auch angelegt (ansonsten bekommt man ja diese freundlichen Fehlermeldungen) - siehe Anhang.
aber:
ich kann tun was ich will, ich erhalte beim Aufruf des Reports immer die Abfragemaske "Parameterwerte eingeben"
hat es eigentlich iregndwelche Probleme mit den so erstellen SEPA_XML-Dateien gegeben ???
Hntergrund:
lt. Anlage 3 der Schnittstellenspezifikation für die Datenfernübertragung zwischen Kunde und Kreditinstitut gemäß DFÜ-Abkommen „Spezifikation der Datenformate“
Version 2.7 vom 25.3.2013
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)
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);
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
nein, es sind keine verschiedenen Datenbanken u. ich mache die Tests auch von der selben Maschine aus.
Zum String: wie Du schon richtig bemerkt hast, grenzen im Moment nicht alle Bedingungen ein,
das wird sich aber im Echtbetrieb durch Usereingaben ändern;
für den Test reichs mir, wenn sie da sind.
@f_igy,
Ich hab das mit dem Management Studio 10 gerade überprüft:
- nein er zeigt mir sofort nach den 5 Sekunden die Daten an, auch das scrollen geht verzugsfrei, ebenso Pageup, Pagedown oder ziehen mit der Maus.
Der SQL-Code ist selbstgestrickt, da ich es irgendwie nicht hinbekomme im Designer mehrer DB´s einzubeziehen - hab mich aber auch nicht intensiv drum gekümmert, um ehrlich zu sein.
@MorhieX u. HiGHteK,
leider dauert es auch so lange (gefühlt vielleicht ein bisschen schneller - ich hab gerade kein Tiimerprogramm) wenn ich die kompilierte Exe starte. Ich weiss allerdings (noch) nicht,
wie es auf einer Maschine ohne Entwicklungsumgebung ist.
ich habe vergessen zu erwähnen, das ich auch bei C# die reine Ladezeit meine.
Ich habe mir entsprechende Haltepunkte (da_ar.Fill(cKartei);) erstellt und mit F11 gesteppt, so kamen die Zeiten zu stande.
Die Zeit für den Backgroundworker sind aber nicht so genau.
Also habe ich doch auch hier die reine Query-Zeit, oder?
Ich sehe da nicht, wo ich Äpfel mit Birnen vergleiche.