Wow - ja, genau das war's. Das hatte ich vor ein paar Wochen ausgeschaltet - das hatte ich schon völlig vergessen. Nur - danach funktionierte es noch 'ne Weile. Hm...
Was ich auch nicht verstehe: Ich erstelle eine völlig neue JumpList, in der werden keine "recent documents" angezeigt. Nochmals hm...
Dazu gleich noch 'ne Frage: Beim Programmstart wird eine JumpList angelegt. Wenn ich jetzt eine neue erstelle, wird die auch angezeigt. Ist die alte JumpList dann gelöscht oder müsste ich sie korrekt über dispose entfernen?
Nee, dispose geht nicht, hab's probiert, vor allem komme ich an die vorhandene gar nicht ran, um sie zu aktualisieren. Meine Frage war also blöde Frage?
Viele Dank für den exzellenten Tipp - ...lypô
Danke, prüfe ich später, muss wech.
VG ...lypô
Hallo,
in meinem Programm wird zu bestimmten Zeiten eine JumpList erstellt. Bisher ging das tadellos, seit neuestem erhalte ich eine Fehlermeldung:
Fehlermeldung:
System.UnauthorizedAccessException
HResult=0x80070005
Nachricht = Custom categories cannot be added while recent documents tracking is turned off.
Quelle = Microsoft.WindowsAPICodePack.Shell
Stapelüberwachung:
bei Microsoft.WindowsAPICodePack.Taskbar.JumpList.AppendCustomCategories()
bei Microsoft.WindowsAPICodePack.Taskbar.JumpList.Refresh()
...
Ich weiß nicht, wie das "recent document tracking" aus- oder eingeschaltet wird. Ich habe bewusst da auch nichts geändert, deswegen vermute ich, dass der Grund für die Fehlermeldung ein anderer ist.
Hier etwas Code:
JumpList jlist = JumpList.CreateJumpList(); // JumpList erzeugen
//return; // zum Abschalten, dammit der Rest des Programms funktioniert
const string op = " öffnen", st = " starten"; // zur Vervollständigung
#region _Ordner_Öffnen_
JumpListCustomCategory pCategory = new JumpListCustomCategory("Verzeichnis" + op); // Kategorie Verzeichnis öffnen
jlist.AddCustomCategories(pCategory);
string[] a_lnk_db = // Pfad, Titel, Iconpfad
{
global.mtgpfad, // Pfad zu den Daten (H:\)
"Infos",
@"....ico",
global.mpfad, // Pfad zum Arbeitsverzeichnis
"... (Debug)",
@"....ico"
};
for (int i = 0; i < a_lnk_db.Length; i++) // in ... öffnen
{
pCategory.AddJumpListItems(
new JumpListLink(a_lnk_db[i], a_lnk_db[++i])
{ IconReference = new IconReference(a_lnk_db[++i], 0), }); // Exe: ..._db
}
#endregion
jlist.Refresh(); // Exception !!!
Infos über den Editor:
MS VS Community 2017, Version 15.9.50
Net Framework, Version 4.8.04.084
Kann jemand helfen?
Danke für den Link, den hatte ich nicht gefunden.
1tsd. Euro - nun, bei bis zu 70 PDFs pro Jahr sind das knapp 15 Euro pro PDF - zu teuer, denn ich muss nur den Text auslesen.
PDFPig machte auf mich einen guten Eindruck. Ich werd's mal probieren - schrieb ich ja schon.
Danke, viele Grüße - ...lypô
Hm. Danke für die Info. Ich habe schon versucht, den Preis herauszubekommen. Wozu die meinen Namen und alle anderen persönlichen Daten dazu brauchen ist mir unverständlich.
Also wäre z.B. PdfPig eine Alternative? Da habe ich Probleme mit der Codierung, habe nur sehr begrenzte Infos dazu gefunden. Na, mal sehen, ob ich's hinbekomme.
Viele Grüße und Danke - MoaByter
hallo,
in meinem Programm muss ich PDF-Dateien auslesen. Bisher ging das mit iTextSharp auch ganz gut, aber seit die PDFs in der Version 1.7 (davor 1.4) vorliegen, funktioniert das nicht mehr. Also habe ich iText7 in der Version 7.23 installiert, da dabei nur wenig Code zu ändern ist. Beim Testlauf stellte ich dann fest, dass die Unterscheidung für Groß- oder Kleinbuchstaben für das Programm wohl nicht relevant ist.
Rufe ich die Datei über z.B. SumatraPDF auf, steht alles in Großbuchstaben da, iText7 gibt mir aber zurück:
"FüR DIE BunDESREPuBlIK DEuTScHlanD". Was soll das? Hat jemand 'ne Erklärung, gibt's eine Lösung dazu?
Die korrekte Groß/Kleinschreibung brauche ich unbedingt!
string inhalt;
using (PdfReader pdf = new PdfReader(daten)) // daten: MemoryStream
using (PdfDocument doc = new PdfDocument(pdf))
{
SimpleTextExtractionStrategy strategie = new SimpleTextExtractionStrategy();
inhalt = PdfTextExtractor.GetTextFromPage(doc.GetPage(i), strategie).Trim();
}
Hallo,
wie ich den Wechsel in den Energiespar-/Ruhemodus abschalte, weiß ich mittlerweile und es funktioniert auch gut:
SetThreadExecutionState(...);
Nur ... Wie frage ich ab, ob der Timer für diesen Modus ein- oder abgeschaltet ist? Mit
GetThreadExecutionState();
funktioniert's nicht, hab' ich schon probiert, wird nicht angeboten.
Weiß jemand 'ne Antwort? Danke.
Aha, dann Danke, ich kann mich dem allerdings wahrscheinlich erst am Sonntag widmen.
Ich werde berichten.
Viele Grüße - ...lypô
Danke der Nachfrage!
Mittlerweile habe ich ein BackUp gefunden, ist gar nicht so alt: Nov. '21. Als Orientierung hätte es gereicht. Ich hatte aber die Gelegenheit beim Schopf ergriffen und das Design beim Neuerstellen überarbeitet (was ich schon immer mal tun wollte 🙂). Jetzt ist alles in sich konsistent, vor allem die Namensgebung und Anordnung der Controls.
Mit dem IL.Spy-Tool komme ich nicht so richtig klar. Verstehe ich das richtig, dass es eine Art AddOn für VS ist (Nuget)? Und dann gibt's ein weiteres Problem: Ich habe bei mir keine DLLs. Alles ist der Einfachheit halbe in der exe versammelt. Nicht günstig, besonders, wenn was verloren geht. Damals, beim Beginn mit dem Programm, kam ich mit der DLL-Erstellung nicht klar und habe mich nie wieder darum gekümmert. Das werd'ich wohl auch mal in Angrfiff nehmen müssen.
Es ist halt ein Programm nur für mich, für einen ganz speziellen Zweck - eine schwache Ausrede, auch das weiß ich.
Jetzt lege ich aber brav & artig Updates nach jeder Veränderung an. Manchmal lernen Menschen aus ihren Fehlern. 🙂
Viele Dank, gehabe dich wohl, bleibe gesund - ...lypô
Auch dir Danke, ich werd's mal probieren. Mal sehen, viel gerade vom Designer das Programm mir wieder herstellt.
Danke für den Tipp. Ich werde das diesbezüglich Verpasste nachholen.
Leider weiß ich nicht, warum der Fehler auftrat. Ich habe in der Form1.cs lediglich eine Methode löschen wollen. Diese wurde wg. eine sversehentlichen Doppelkilicks auf einen Button im Designer angelegt, dort hatte ich den Eintrag bereits entfernt, der wurde aber nicht gelöscht, also wollte ich es manuell tun. Dann wurde alles weiß, nach einiger Zeit schloss sich das Programm. beim Wieder-Öffnen sah ich dann das Melheur.
So what ... Fehler sind dazu da, dass mann daraus lernt...
@ T-Virus:
Nun, mit Repository hatte ich mich nur ganz am Anfang beschäftigt, daraufhin lief alles schief - vermutlich wegne eines Fehlers meinerseits - weswegen ich das dann gelassen habe. Ich war ja noch am Lernen.
@ Abt:
Das ist aktiviert, nur ist das Verzeichnis leer - warum auch immer. Leider ist__ es ein schmerzliche Erfahrung und wird es für ein Weilchen bleiben. ..._schluchz! _ 🙂
@ beide
Okay, Danke euch beiden. Dann werde ich mich mal dran machen....
Bei mir ist ein ziemliches Malheur passiert. Im Designer ist ein ganzer Bereich gelöscht worden. Kann man den nicht wiederherstellen? Ich finde keinen Menüpunkt dazu.
Rückgängig ist keine Option, da das Programm abgestürzt war und ich den Fehler erst beim Neustart entdeckte.
Der gelöschte Bereich - und das macht das Ganze so dramatisch - enthielt die wesentlichen zweidrittel meines Programms; den manuelle wiederherzustellen dürfte 'ne kanppe Woche dauern. Legt VS nicht automatisch ein Backup an?
Danke für Hilfe!
PS.: Die exe-Datei funktioniert, nur benötige ich den Designer mit allen Einträgen.
Du möchtest den String für Regex escapen?
In dem Fall: Regex.Escape(String) (Docs)
Das escaped dir alles, was eine gesonderte Bedeutung haben könnte.
...
Leerzeichen durch \s+ ersetzen: Simples Replace. Bedenke aber, dass \s mehr erkennt, als nur Leerzeichen.
Die Zeilenumbrüche entfernen: Auch simples Replace, mach das aber am besten mit Environment.NewLine (Docs)
...
Für sowas ist Regex eigentlich ideal ^^
>
Wie es genau aussehen muss und was Du damit machst, musst Du noch anpassen.Und da siehst Du auch gleich ein wirklich gutes Regex-Tool.
Das sind doch mal zwei exzellente Tipps. Regex.Escape kannte ich noch gar nicht, muss also mein Wissen über Regex auf jeden Fall aktualisieren.
Bedankt!
Mittlerweile funktioniert's wie gewünscht, dein Tipp mit "\s" war ideal - eben weil das mehr als Leerzeichen erkennt.
Nun will ich die ganze Sache noch etwas ändern und erweitern, wobei mir das Regex.Escape durchaus helfen könnte.
Nochmals bedankt! 👍 👍
Was willst du denn genau machen? Vlt. wäre ja ein HTML (wie AngleSharp) parser besser geeignet
Das HTML ist nicht das Problem, der ganze Kram liegt nur in HTML vor, deswegen die vielen Tags darin. Die müssen allerdings auch erkennt werden, was gelungen ist. Dennoch oder trotzdem oder wie auch immer Danke für deine Antwort. 🙂
Meines Wissens kann die Zwischenablage Daten in mehrerem Variationen speichern. Vielleicht setzt du die falsche?
Guck dir doch den funktionierenden Inhalt mit GetData an, dann siehst du möglicherweise den entscheidenden Unterschied zu dem was du setzt.
Es geht nicht um das GetData(), sondern um das SetData(). Das GetData() oder wie auch immer macht dann der Firefox. Dort will ich die Daten aus der Zwischenablage in ein <textarea>-Eingabefeld einfügen.
Über Strg+C (WebBrowser) und Strg+V (Firefox) klappt das prima, es funktioniert nur nicht, wenn ich die Daten über SetData in die Zwischenablage bringe. SetData(DataFormats.Html) und SetData(DataFormats.Text) schreiben die Daten des WebBrowsers als Klartext (mit allen Html-Tags) in die Zwischenablage. In der <textarea> erscheint dann der Html-Text oder eben nur der Text, aber nicht der formatierte.
Alle anderen SetData(DataFormats...) sind nicht lesbar oder werden nicht gelesen.
Das ganze ist nicht von fundamentaler Bedeutung. Ich wollte es nur ausprobieren und dabei kam diese Frage auf.
Wie schon gesagt/geschrieben werde ich mich mal weiter informieren, ein paar Gedenkanstöße habe ich ja erhalten.
Viele Grüße - Moabyter
Das doc wird im Browser korrekt angezeigt, ist ganz korrektes, einfaches Html, und wenn ich es dort komplett markiere, egal ob manuell oder mit
webbrowser.Focus();
webbrowser.Document.ExecCommand("SelectAll", true, null);
markieren lasse und dann mit Strg+C den Text heruakopiere und dann bei FF einfüge, funktioniert es wunderbar, nur eben nicht mit
Clipbord.SetData(...);
Meine Freundin und ich haben dazu gestern zwei recht interessante Links gefunden, auch wenn's mir noch nicht geholfen hat:
https://de.wikipedia.org/wiki/Zwischenablage
https://docs.microsoft.com/de-de/windows/win32/dataxchg/clipboard-operations#cut-and-copy-operations
So ganz wenig ist das nicht, was da passiert.
Nunja, erstmal Danke für deine Antwort, ich werd' mal weiter suchen, es geht ja auch so.
Wäre nur interessasnt zu wissen, was da alles passiert und wie.
hallo,
jetzt sagt bitte nicht: "das kopiert", denn das ist nur die halbe Wahrheit.
Beispiel:
Ich erhalte eine Mail mit formatiertem Text, also mit bold und kursiv und sowas.
Den Text markiere ich, dann Strg+C und füge das Kopierte in ein Textfeld (<textarea>...</textarea>) im Browser FF ein. Funktioniert wunderbar, aber ich möchte es mit C#-Code realisieren.
Ich versuchte
dynamic doc = webbrowser.Document.DomDocument;
Clipboard.SetData("html", doc.selection.createRange().htmltext); // statt "html" habe ich auch 'DataFormats...' versucht
aber es gelingt nicht, die Zwischenablage ist über
string str = Clipboard.GetData(DataFormats.Html) + "";
nicht auslesbar, auch mit anderen DataFormats nicht.
Wieso also funktioniert es mit Strg+C? Was genau macht Strg+C?
Hat jemand 'ne Idee? Danke!
Nochmal deutlicher:
Sind sie nicht. Ich ersetze ganz gezielt die Leerzeichen mit "\s+", denn genau dort befinden sich die Zeilenumbrüche (die ja dank deiner Tipps als Whitespace gelten). Und die ZU stören eben bei der Suche, das Programm findet dann den gesuchten Text nicht, da der eben keine ZU hat bzw. haben sollte (hat er leider manchmal doch, was merkwürdig ist).
Ich gebe dem Regex mit dem '\s+' die Anweisung, die ZU in den Wortzwischenräumen zuzulassen bzw. zu ignorieren.
Die Länge des Originaltexts darf ich nicht ändern, da sonst die Indices nicht mehr stimmen.
Und: den Regex an den Originaltext anzupassen fand ich einfacher als umgekehrt.
Scusi, die Antwort hat etwas gedauert, ich hatte heute reichlich anderes zu tun.
Ich verstehe den Sinn von dem Code nicht ...
Zwei mal Replace? Warum?
Wenn Du auch Klammern ersetzen willst, dann mach: [\s()]+
Nein, die Klammern will ich nicht ersetzen, sondern maskieren. Der im WebBrowser selektierte Text dient ja als Regex-Muster und die Klammern würden dabei als Gruppe behandelt.
Ich habe die Regex jetzt einzeln aufgelistet:
string s_patt = Regex.Replace(tb_qts.Text.ToLower(), "([()])", "\\" + "$1"); // Escape-Zeichen für Klammern
s_patt = Regex.Replace(s_patt, " +", "\\s+"); // Ersetzen der LeerZ. mit \s+
s_patt = Regex.Replace(s_patt, "\r\n", "");
Und das "äußere" Replace ist immer noch falsch herum. Nochmal: Zähle die Parameter der Methode, der zweite Parameter muss das Pattern sein. Du versuchst ein Leerzeichen durch '\s+' zu ersetzen.
Sind sie nicht. Ich ersetze ganz gezielt die Leerzeichen mit "\s+", denn genau dort befinden sich die Zeilenumbrüche (die ja dank deiner Tipps als Whitespace gelten). Und die ZU stören eben bei der Suche, das Programm findet dann den gesuchten Text nicht, da der eben keine ZU hat bzw. haben sollte (hat er leider manchmal doch, was merkwürdig ist).
Und die Klammern außerhalb der eckigen Klammern sind eine Gruppe, die brauchst Du nur, wenn Du einen bestimmten Teil des Matches erreichen möchtest.
Regex.Replace(tb_qts.Text.ToLower(), "([()])", "\\" + "$1")
Ja, aus der Gruppe ("([()])") - ist ja nur die Nr.1 - lese ich die gefundene Klammer aus - '(' oder ')' -, die dann mit Maskierung ("\" + "$1") versehen wird: '(' oder eben ')'. Rückbezug oder oder so ähnlich.
Für mich sieht das ein bisschen so aus, als würdest Du hier durch try&error durch vor irren wollen.
Bei Regex wirst Du damit nicht glücklich, Du solltest dir dir Grundlagen anschauen.
>
Ganz so schlimm ist es nicht, aber das RegexLab-Tool hilft nicht immer weiter, manches muss ich da probieren. Tatsächlich funktioniert es jetzt wie gewünscht bis auf eine kleine Kleinigkeit:
Absatzübergreifend findet er den Text auch jetzt nicht. Das dürfte an dem '\s+' liegen, denn in den Absatzumbrüchen stehen Sachen wie '<div> </div>' oder '<br>', eben keine WhiteSpace-Zeichen. Die könnte ich natürlich auch noch 'rausnehmen, aber das wird aufwendiger als nötig.
Regex-Tutorials habe ich einige, und auch gelesen, wenn auch nicht alles. Unter anderem habe ich die Funktionen von '\s' nicht gesehen - das wundert mich schon etwas. Ich weiß aber, dass ich über Regex noch längst nicht alles weiß. Denk' dran: Is'n altes Gehirn, dass sich nicht immer alles schnell merken kann. Ich brauche dazu Praxis, und die erarbeite ich mir gerade - unter anderem mit deiner Hilfe.
Also nochmals viele Dank, wenn ich mal Tipps für das 3-Schichten-Modell brauche, frage ich wieder, werde mich aber erstmal belesen.
einges habe ich jetzt schon ausgelagert, aber es gibt Methoden, die sehr intensiv an der GUI arbeiten, das ginge dann mit subclasses nur mit Invoke, was auf Dauer recht anstrengend ist.
Dennoch werde ich den Artikel gerne lesen.
tschüss bis demnächst mal - MoaByter
Jau, Danke, habe ich umgeschrieben.
allerdings habe ich die Klammer auch noch mit 'nem Regex korrigiert:
string s_patt = Regex.Replace(Regex.Replace(tb_qts.Text.ToLower(), "([()])", "\\" + "$1"), " ", "\\s+");
Vielleicht ginge es ja mit zweimaligem Replace wie in deiner Version schneller ... naja, so sieht's schöner aus.
Das '\s+' hat mir noch Kummer bereitet, ich hatte es zuerst in Klammern und die vergessen 'rauszunehmen, da ging die Geschichte nur mit einem Zeilenumbruch.
Jetzt läuft's aber, der Tipp ist Spitze, werde meine anderen Regex auch überpürfen. Da sind z.T. richtige Ungetüme drin, da ich unterschiedliche Texte bekomme.
Und ich hab's in eine extra Klassse gesetzt ... ... ... und es funktioniert trotzdem! 🙂) Auch wenn's nur 67 Zeilen sind.
So lernt mann, naja: ich, immernoch dazu.
Also sei Bedankt, gehasbe dich wohl, ich muss inne Heia, mich müdet mittlerweile.
Viele Grüße - MoaByter (kommt von Moabit, mein Berliner Bezirk)
Öhm - ja, ich glaube, bezüglich des Patterns habe ich dich verstanden, hab's nämlich gerade mal ausprobiert:
string s_patt = Regex.Replace(tbQntTextSuche.Text.ToLower().Replace("(", "\\(").Replace(")", "\\)"), " ", "([\\s\\r\\n]+)"),
Also erst den Klammer.Replace, dann das Regex. Meintest du das so? Funktioniert nämlich. Deswegen hat das Muster - nur das Muster - im RegexLab funktioniert, da ich mit dem normalen Replace die Klammern wieder verändere. Fiel mir erst jetzt beim Debugging auf.
Tja, und die Sache mit dem '\s' wusste ich nicht. Erstaunlich, dass trotzdem alle meine anderen Regex so gut funktionieren. Ich dachte, ich wäre darin einigermaßen bewandert - Duning-Kruger-Effekt?
Also herzlichen Dank für deine Hilfe! Ich hatte so sehr im Netz gesucht und nur Unpassendes oder Müll gefunden (im_coder.com).
Gehab dich wohl, viel erfolg - MoaByter
??? hallo Palladin007,
was meinst du mit zweitem Parameter? Und mit '\s' findet der Regex doch nur die Leerzeichen. Die habe ich mir im Muster erspart, dadurchs wird's für mich leichter lesebar.
Was ich in meinem Text nicht gezeigt habe, ist die eigentliche Suche, aber dabei ist nix überraschendes:
Match m = Regex.Match(s_rtbtxt, s_patt, RegexOptions.Singleline);
Wie gesagt, im RegexLab funktioniert es genau so, wie ich's aufgebaut habe.
Hallo,
wie finde ich in einen Text mit Zeilenumbrüchen gemäß einer Vorlage ohne Zeilenumbrüch?
Beispiel:
...emil
und
luise...
möchte ich finden, habe als Suchmuster aber nur ...emil und luise... ohne Zeilenumbrüche.
Das heißt also, der Reguläre Ausdruck muss die Zeilenumbrüche zwischen den Wörtern akzeptieren. Im Regex klappt's. Ich habe das Suchmuster etwas kompliziert aufgebaut: Ich ersetze die Leerzeichem im Suchmuster durch @"([ \r\n]{1,5})" und vor Klammern im Text werden Backslashes eingefügt.
wie gesagt: Im RegexLab klappt's, in meinem Programm nicht. Programmzeile für das Regex-Muster:
string s_patt = Regex.Replace(textBox.Text.ToLower(), " ", @"([ \r\n]{1,5})").Replace("(", "\\(").Replace(")", "\\)");
Kann jemand helfen? Wäre toll!
Die Laufzeit ist allerdings nicht wirklich ein Problem - auch wenn ich mit daran denke.
Nun, den Code, den ich einsetze/schreibe, verstehe ich auch, was beim Delegaten zuerst wirklich ein Problem war. Aber Threading und Tasks sind doch recht einfach. Mir fehlt wohl eher der Überblick über die Möglichkeiten, denn oft genug gibt's mehrere Wege, eine Aufgabe zu lösen.
Tut's schon, bin Rentner. Seit 1. Januar. 🙂)
MVVM - ja, davon hab' ich schon gelesen. Da bin ich noch am Grübeln, wie ich das umsetze. Aktuell ist mein Programm vor allem schnell, was nach Möglichkeit so bleiben sollte. Da ist allein schon Invoke ein Hindernis: "dgv.Invoke..." - und das 50-150 mal - dauert.
Ich frag' doch, wenn ich nicht weiter weiß. Bin doch da! 🙂)
Vieles finde ich schon auch selbst im Web. Das hat den Vorteil, dass ich auch zu anderen Themen Ideen finde, die sind bei mir schon eingeflossen.
Die genannten Konzepte sind für mich durchaus ein Thema, meist hakt's an den Ideen und Entscheidungen für's Umsetzen.
Es ist schade, dass ich in meinem Bekanntenkreis keine Programmierer habe, zwei Admins zwar, aber die können's nicht (richtig).
Der Rest sind Lehrer und ein Elektromeister. Elektriker war mein Job bis vor etwa 15 Jehren.
An den Tasks bin ich schon 'ne ganze Weile, nach Deleagten/Invoke und Threads sind die jetzt dran, die sollen ja viel einfacher sein. Ist so schwer auch nicht - bis auf die Stolpersteine: SetApp... z.B., denn diese Fehlermeldung bekomme ich. Dazu werde ich 'nen neuen Thread aufmachen, muss nur schauen, wie ich den Code einbringe. Da heißt's zwar Thraeds, aber ist halt in eine(r/m) Task.
Ja, mehr oder weniger privat, als is' nur fürt mich.
Beispiel: RennInfo-Texte in 'ner word-Datei. Die öffne ich in meinem Programm, das speichert sie als *.html und ruft sie auf. Der Text wird dann passend umgewandelt, automatisch in Absätze unterteilt und "bereinigt". dann nur noch der Klick auf "Senden" und ich kann ander Dineg tun. Für sowas brauche ich 2 oder 3 Minuten mit allem drum und dran, bekomme aber 'ne halbe Stunde bezahlt. That's why! Und es gibt mehrere Bereiche, in denen ich arbeite. -> Anhang
Ich habe mir schon Gedanken gemacht, wie ich es aufbaue. Nur bin ich erst vor Kurzem auf das 3-Schichten-Modell gestoßen. Am Anfang war ich eher stolz, dass das Programm recht gut läuft, was es ja auch tut. Nur die Vielzahl der erweiterungen brachte mir dann die Probleme.
Alte Fehler - hihihi - naja, da hat's reichlich. Ich studiere mal wieder das Handbuch, dicke Schwarte von Galileo-Computing. Die Microsoft-Seiten sind nicht immer hilfreich, weil ich oft nur die Hälfte verstehe oder die Tipps nicht anpassen kann.
Das Programm ändern kann ich sowieso nicht. Ich muss es tatsächlich neu schreiben, denn es muss ja weiter funktionieren - is' mein Minijob. Da brauche ich es mehrmals täglich.
Ja, is' WinForms, kerin WPF. Mit dem kam ich nicht klar, müsste ich mal wieder versuchen.
Achja ... "Sytaxfehler"! Das Wort habe ich gesucht. Altzheimer? Das Alter dazu hätte ich...
Bedankt und ich werde mal weiter machen. Eine Frage kommt vielleicht noch - "SetAppartmentStaste" bei Tasks. CS1061. mal sehen, ob ich was finde.
Bis denne, gehabt euch wohl und viel Erfolg bei allem, was ihr tut & treibt - Moabyter
Ach, ich arbeite ganz gerne damit. Mittlerweile kenne ich auch 'nen Haufen seiner Schwächen. Ich hatte es mal geübt, alles manuell zu erstellen, aber für's hübsch aussehen ist er doch 'ne gute Hilfe.
Die Frage nach dem Positionieren der event-codes war ja auch nur 'ne Frage, die Antwort hatte ich schon befürchtet. nun gut, mach' ich' eben händisch.
Jetzt mal 'ne andere Frage: Hier gibt's doch 'ne Liste der Compiler-Fehler-Meldungen (CSxxxx), ich finde die aber nicht. Wo könnte ich Erfolg haben?
Damals wusste ich es nicht besser. mit dem Erstellen des Programms - was wie gesagt für etwas ganz kleines, tabellarisches gedacht war - habe ich C# gelernt. Davor konnte ich nur etwas javascript, hatte alles im Browser laufen.
Ich habe im Designer knapp 200 Events, und ich muss viel in die GUI schreiben, da habe ich schon Probleme mit Klassen, für jede Datei (~60) eine und ein paar zusätzliche. Ich bearbeite Texte, die ich zugesendet bekomme, erweitere sie mit Daten von anderen Webseiten (alles legal und angemeldet) und lade diese dann ins BackOffice hoch. Das sind schon einiege Themenbereiche. Ich müsste mir also erstmal Gedanken machen, wie ich das Ganze strukturiere.
Nun, das Programm kenne ich in- und auswendig, da ist das nicht so schlimm, dafür ist's schön schnell. Nachteile sind die bekannten.
Zum Teil ist noch Original-Code drin, an dem es nichts zu verbesern gibt - jedenfalls nichts nennenswertes.
Alles nicht so ganz einfach, aber ich bin und bleibe dran - gezwungenermaßen.
Naja ... Das Programmm wurde vor 9 Jahren erstellt für eine kleine Sache (Excel-Tabellen-konsolidieren war nicht der Brüller).
Mittlerweile sind alle Dateien zusammen - ohne generierten Code und ohne Kommentarzeilen - vielleicht 10-, 12tsd Zeilen, wobei die Form1 mit 3,5tsd Zeilen den größten Anteil hat.
Vieles habe ich schon umgearbeitet, immer wenn was neues 'reinkommt ganz besonders, aber alles neuschreiben und die GUI neu codieren wäre 'ne Arbeit für viele Wochen. Nun, ich werd's wohl mal anpacken müssen. ...ach seufz!
Danke erstmal für deine Hilfe, viel Erfolg bei deinen Arbeiten - Moabyter
Alles richtig und verständlich. nur ist diese Klasse etrwas größer und er setzt den Code in den zugeklappten Teil nach ganz unten. In diesem Bereich arbeite ich seit Eeewigkeiten nicht mehr, deswegen die Frage.
Wäre schön, wenn es einen Trick gäbe, mit dem VS überzeugt werden kann, den Code sagen wir mal in Zeile 100 zu setzen.
Im Moment schreibe ich den Code dahin, wohin ich ihn haben will, ist natürlich mehr Aufwand. Den würd'ich mir gerne ersparen.
Hallo,
ein vielleicht etwas merkwürdiges Problem:
Wenn ich im VS-2017-Designer [Entwurf] ein z.B. Klick-Event anlege, packt VS den Code dazu immer an eine bestimmte Stelle (dir mir sehr unbequem ist). Kann ich das irgendwie einstellen? Unter Extras->Anpassen finde ich dazu nichts. Hat jemand 'ne Idee oder geht das gar nicht?
Danke schon mal - Moabyter
Danke für deine Antwort, meine kommt etwas spät, hatte viel anderes zu tun, Scusi.
Ich habe die Seiten über WebView2 mal angesehen, blicke aber noch gar nicht durch. Ich habe das Nuget-Paket zwar installiert, aber wie der WebBrowser lässt's sich nicht einbinden; bei den Tools taucht's jedenfalls nicht auf. Ich werd' mal weiter lesen, vielleicht kommt mir ja noch die Erleuchtung.
Ich bin mir auch nicht sicher, ob der Aufwand lohnt, denn der WebBrowser isz nur zum Anzeigen interner Daten(listen) zuständig, er soll nicht ins Web.
Ja, WebBrowser-Klasse. Steht unter "Tools" und ist somit für mich eben auch ein Tool.
Ähm ... da fehlen ein paar infos:
ich arbeite mit Windows 10, nutze VisualStudioCommunity2017. Ich verwende in meinem Programm mehrere Browser, insgesamt 5 Stück.
Nur bei den 3 Browsern mit eingeschalteter Navigation tritt der Fehler auf, vor ein paar Stunden noch funktionierte es trotzdem.
Wenn ich jetzt auf
AllowNavigation = false;
stelle, ändert das nichts. Ich weiß mir einfach keinen Rat mehr. Es ist, als würde b...
Aha - Fehler vielleicht gefunden, ich änderte die Position des "e.Cancel=true;" im Navi-Event:
Vorher:
private void OnWbNavigating(object sender, WebBrowserNavigatingEventArgs e)
{
string lnk = e.Url + ";
e.Cancel = true;
if (lnk.StartsWith("about:")) return;
...
}
Nachher:
private void OnWbNavigating(object sender, WebBrowserNavigatingEventArgs e)
{
string lnk = e.Url + ";
if (lnk.StartsWith("about:")) return;
e.Cancel = rue;
...
}
Mich wundert es etwas, denn ganz vorher stand das "e.Cancel=true;" als
if (link.Contains("about:blank")) e.Cancel = true;
innerhalb des jetzt noch vorhandenen if-Elements. Das müsste das Programm ja nach dem WebBrowser.DocumentText = "xyz" auch durchlaufen haben.
Vielleicht hat jemand einen Tipp dazu? Das wäre sehr nett, Danke!
VG - ...MoaByter
Hallo,
mit dem WebBrowser-Tool habe ich ein merkwürdiges Problem:
Ich fülle mit meinem Programm ein List<string>-Element mit HTML-Text, das ich zum Schluss als String mit dem Befehl
wb.DocumentText = string.Join(rn, l_htm); // rn = Zeilenumbruch, Environment.NewLine
in dem WebBrowser anzeigen lassen möchte. Bisher funktionierte das auch problemlos, jetzt geht's auf einmal nicht mehr, WebBrowser.DokumentText zeigt nur einen Leerstring. Wenn ich es Schritt für Schritt durchfahre, stelle ich fest, dass das Programm die Navigation - OnNavigating(...) - mit WebBrowserNavigatingEventArgs.Url = "about:blank" aufruft, dann zurückkehrt ... und das BrwoserDokument bleibt leer.
Ich hatte das früher schon mal und es mit einem nachfolgenden
Thread.Sleep(100);
lösen können, später war letzteres nicht mehr nötig, funktionierte auch so - warum auch immer. Jetzt aber hilft gar nichts mehr. Woran könnte das liegen?
Den Aufruf des Navigating-Events hatte ich, als der Browser noch funktierte, nicht überprüft, warum auch? Es ging ja alles.
Der HTML-Text ist einwandfrei - nur Text, kein Script o.ä. Weiß jemand Rat?
Ein Screenshot anbei.
VG - ...MoaByter
Danke für eure Antworten!
Also: Ich habe geschlampt, ich hab' 'nen Fehler gemacht - wobei das Schlampen auch schon 'n Fehler ist - und eine Frage ist noch offen.
@hypersurf: Das irritierte mich eben an der Sache.
@Stefan.Haegele: Deswegen schrieb ich 'VS2017':. Alle Controls werden im Designer erzeugt, sind also != null. War zu knapp erklärt, Scusi.
@Abt - und auch die beiden anderen:
ich sollte einfach nicht mehr um 2 Uhr morgens programmieren... 🙁
Die Elemente im DGV[] a_dgv können nicht null sein, es wird als erstes im Form_Load-Event erstellt.
Beim Debuggen war CurrentCell nicht null und trotzdem wurde der Disassambler in Zeile 11 aufgerufen, auch wenn ich statt dgvc.CulumnIndex eine Integer eingesetzte. Warum das? Das ist die offene Frage.
Mein Fehler lag allerdings in der - neuen - Klasse, die die DGVs mit Daten füllt. Es gibt 5 DGVs, das sechste hatte ich per Code ausgeklammert, wg. eines Tippfehlers wurde das aber doch wieder bearbeitet (for-Schleife). Das habe ich übersehen.
Und die Schlampigkeit, dgvc nicht auf null zu prüfen ... Früher war's nicht nötig, es war nie null. Der Code stammt aus meinen Anfangszeiten, als ich gerade C# lernte. Ein schlechte Entschuldigung.
Jetzt - mit Null-Prüfung - nötig, da die Zeilen der DGVs mit dgv.Rows.Clear() gelöscht werden, funktioniert's tadellos.
Die Prüfung am Schluss bezieht sich eigentlich nur auf 'Value', das 'dgvc != null' stand nur zur Vervollständigung drin. Der 'Value != null'-Test war entscheidend.
Ich hab's jetzt also geändert:
actCol[aSTab] = actC = dgvc == null ? -1 : dgvc.ColumnIndex; // aktuelle CurrentColumn oder -1
tsslColValue.Text = actC + 1 + "/" + dgv.ColumnCount; // ToolStripStatusLabel: Text eintragen
(dto. für .RowIndex), alles andere bleibt so. Ich brauche in actCol[]/actRow[] einen verwertbaren Wert, deswegen so.
Fehlermeldung:
Also bleibt nur noch die Frage, warum beim Debuggen der Disassembler aufgerufen wird, das verstehe ich nicht.
Wie gesagt, beim Normalbetrieb stört's nicht, mich hat's gestern/heute-morgen nur völlig iriitiert, weswegen ich den Ablauf gar nicht erst getestet hatte.
Mit dem nullable-System beschäftige ich mich gerade, hatte es bisher nur teilweise verwendet (string s = dgv[x,y].Value? "abc"; )
Danke nochmals, viele Grüße, bleibt gesund - ...lypô
Hallo,
ich habe in meiner Anwendung - erstellt mit VS2017 - ein ToolStripStatusLabel, das mit einem Text vorbelegt ist: "-". In dieses Label werden im Verlauf die Koordinaten der CurrentCell einer Tabelle eingetragen, das ging über 7 Jahre auch ohne Probleme. Ich habe jetzt einige Variablennamen global geändert ... und schon gibt's Ärger.
/// <summary>
/// Setzt System-Variablen und Statusanzeige auf die Adresse der aktiven Zelle
/// </summary>
/// <date>210406-2330</date>
void SetStatusLabel() // Anzeige der Statusleiste setzen
{
DataGridView dgv = a_Dgv[aSTab]; // a_Dgv: DGV-Array
DataGridViewCell dgvc = dgv.CurrentCell; // dgvc: DGV-Zelle CurrentCell
actCol[aSTab] = actC = dgvc.ColumnIndex; // aktuelle CurrentColumn
tsslColValue.Text = actC + 1 + "/" + dgv.ColumnCount; // ToolStripStatusLabel: Text eintragen -> FEHLER!
actRow[aSTab] = actR = dgvc.RowIndex; // aktuelle CurrentRow
tsslRowValue.Text = actR + 1 + "/" + dgv.RowCount; // ToolStripStatusLabel: Text eintragen -> FEHLER!
if (dgvc != null && dgvc.Value != null) // wenn CurrentCell und CC-Value != null...
tsslWertValue.Text = (dgvc.Value + "").Replace("&", "&&"); // Ampersand im Text ersetzen
ststMid.Refresh(); // Aktualisieren
}
Die Variablen stimmen alle, die Werte sind: dgvc != null, aSTab = 4, dgv.ColumnCount = 6, .RowCount = 1. Die Struktur, der Aufbau, ist über all die Jahre gleich geblieben - was sollte ich auch ändern? Das Verrückte: Manchmal funktioniert's, allerdings nur beim Debugging.
Folgende Fehlermerldung:> Fehlermeldung:
StackTrace:
System.Reflection.TargetInvocationException: Ein Aufrufziel hat einen Ausnahmefehler verursacht. ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei trotto.Trotto.SetStatusLabel() in ...\Trotto.cs:Zeile 769. (Das ist die erste tssl-Zeile, 11)
Nur ist da nix null. Das einzige, das null sein könnte, ist dgv.ColCount und .RowCount, die sind aber klar definiert != null: Wert = 6 bzw. 1.
In Zeile 11 bzw. 14 (tssl) springt der Debugger dann in den Disassembler. Siehe Anhang.
Was also ist da los? Was übersehe ich? Es hatte doch funktioniert, warum jetzt nicht mehr?
Ich habe die Screenshots vom Disassembler und der Aufrufliste angehängt.
Ein interessanter Artikel - warum hab' ich den bei meiner Suche nicht gefunden? Bedankt jedenfalls!
Mal sehen, ob ich das so bei mir einbauen kann, einige Anpassungen muss ich vornehmen, da die Tabellenformatierung bei mir in der jeweiligen Datei notiert ist. Und ich muss die Zeilen-, Zellenfarbe ändern können, könnte klappen.
Den Bearbeitungscode in meinem Programm muss ich regelmäßg prüfen und b.B. anpassen, da die Webseiten, die ich - erlaubt - auslese, auch weiterentwickelt werden.
Tatsächlich könnte ich mit DataBinding auch an anderen Stellen viel Code vereinfachen/ersparen.
Teilweise bzw. in Ansätzen ist das 3-Schicht-Modell schon realisiert, da ziemlich schnell klar wurde, dass es kompliziert wird. Mangels Informationen - und Zeit - habe ich es leider auf "später...!" verschoben, jetzt rächt sich das ... naja, is' ja noch nicht zu spät.
Also euch allen herzlichen Dank für eure konstruktiven Beiträge, sie haben mir sehr geholfen. Manchmal braucht's eben ein paar Gedankenanstöße - fertige Lösungen bringen nichts, da ich's dann nie lerne. Schließlich hab' ich mit dem Bau des Programms C# in der praktischen Anwendung gelernt. So ist's doch eher überraschend, dass das Programm jetzt seit 8 Jahren recht problemarm läuft.
Dass Tasks und das Async/Await-System erstmal eine Lernhürde darstellen: absolut!
Das meinte ich. Aber durch muss ich, wenn's mit dem Programm was werden soll. Ich geh' mal davon aus, dass ich den Minijob auch bei Rente behalten werde.
Verstehe ich das mit dem DataBinding richtig: Wenn sich die Datenquelle ändert, wird diese Änderung automatisch ins Dgv übernommen? Ich habe für meine Tabellen eine textbasierte Datenbankdatei, Erweiterung .mtgt. Da stehen die Tabellenformatierungsdaten drin, 9 Zeilen, und die Zelleninhalte (Text). Die kann ich aber nicht anbinden/auswählen, vermutlich weil kein definiertes Protokoll existiert. Ich habe allerdings eine Klasse, mit der ich die Tabellen aus den Dateien lade und in einer Variable speichere, aber ob man das Protokoll nennen darf? Übrigens werden die Datenbankeinträge tatsächlich nur und ausschließlich programmgesteuert vorgenommen. wenn da was schief läuft, muss ich die Software ändern, da die aufegrufene Quelle/Webseite sich geändert hat. Ich benötige also keine Eingabemaske für die Datenbank.
Da denke ich mir, ich könnte in dem Feld für die Variable eine Exception starten, wenn sie geändert wird - oder wie startet man ein Event? Aufgrund dieses Events/dieser Exception müsste dann die zugehörige Tabelle neu geladen werden. Ginge sowas? Ich bastele gerade daran.
Ah: event – C#-Referenz
Ich könnte auch pro Tabelle ein verstecktes Textfeld anlegen mit "OnTextChange"-Event.
Erst einmal ein braves Dankeschön an euch alle: Abt, Th69, FZelle, inflames2k!
Bisher hatte ich in meinem Programm mit BackgroundWorkern gearbeitet, bei dem das ReportProgress schwierig und aufwändig war, bis man mir sagte, der sei veraltet, besser seien Threads oder Tasks. Mit Threads funktierte alles recht gut, nur die Datenüber- und -rückgabe gestaltete sich problematisch. Also Tasks? Die sind offensichtlich auch nicht ganz ohne, zu denen fehlt mir noch das Wissen. Auch wenn Abt meint, das sei auch mit Tasks super einfach ... wenn man weiß wie's geht, stimmt das wohl, wenn nicht, muss man sich durchbeißen und lernen.
Zu meiner Person: Ich komme aus der HTML/javascript-Ecke, davorvorvor TI-58 (programmierbarer Taschenrechner), Schul-, Studienzeit Mitte 70er Jahre).
Mit diesem meinem Programm begann ich 2013 C# zu lernen - es sollte drei Aufgaben erledigen, dann kamen Webseitenanalysen mit Down- und Uploads dazu. Mittlerweile ist es auf eine Größe angewachsen, bei der es mir echt schwerfällt, den Überblick zu behalten: etwa 2,5MB an selbstgeschrieben .cs-Dateien.
Deswegen dachte ich auch schon an das:
3-Schicht-Modell: Ich bin am Umbau. Da das Programm aber weiter täglich funktionieren muss, ist das nicht ganz trivial. Und da ich es damals noch nicht kannte, hatte ich den KISS-Weg gewählt - überaus erfolgreich, wesegen ich jetzt vor dem Dilemma stehe.
Parallele Programmierung: mit Tasks, TPL, await & Co. sind für mich noch sehr neu - mal abgesehen vom BackgroundWorker.
Deadlock: Irgendwas in dieser Richtung vermutete ich schon, konnte nur nicht den Grund dafür finden, stellte aber schon fest, dass das Programm einfach stehen blieb und nur mit dem Taskmanager abschaltbar war. Der Hauptthread schien tot.
DataBinding: Das habe ich bisher noch nicht genutzt, sondern alle Daten brav & artig in die Tabellen und parallel dazu in Variablen geschrieben, müssen halt nur gleichermaßen aktuell gehalten werden. Nicht ganz einfach, aber mit etwas Sorgfalt zu schaffen.
Async Antipatterns: Bin noch am Lesen, vieles ist mir allerdings schon klar - und davor gewesen, auch wenn ich diese Probleme noch nicht hatte.
ObservableCollection: Das klingt interessant. Mal sehen, was ich darüber erfahre.
Im Moment kämpfe ich allerdings noch mit VS2019Com, davor VS2017Com, das Debugging ist mir kaum möglich, ich bekomme jede Menge Meldungen, "Der Wert der Variable kann nicht angezeigt werden, da sie wegoptimiert wurde". Auch Haltepunkte werden mal eben übersprungen. Aber das gehört zu einer anderen Anfrage, die ich noch erstellen muss. Jetzt muss erstmal mein Programm wieder laufen, sonst gibt's Ärger vom Chef.
Gehabt euch wohl, bleibt gesund - wie gut, dass ein Computer sich nicht mit C. infizieren kann 🙂), viel Erfolg bei euren Aktivitäten,
viele Grüße - ...lypô aus Moabit.
Auha! Danke für deine ausführliche Antwort, ich werde etwas Zeit brauchen, um alles zu durchforsten.
Die Zeile 6, "string.IsNullOrEmpty..." ist doch aber nötig. Ich muss das Resultat auf null prüfen, denn es wird weiter verarbeitet, und bei task.Result == null stürzt das Programm ab.
Das Realisieren mit dem Zwischenspeicher ist mit noch nicht klar, ich belese mich weiter.
Mit Task.Run... kam ich nicht weiter, sollte wohl von selbst starten, tat es aber nicht. Meine Vorlage:
Task Klasse
Es läuft ja die gesamte for-Schleife in dem Task. An der Stelle ist nix parallel. Ich wollte noch zwei Prozesse zusätzlich parallel laufen lassen, aber wenn ich nicht mal mit einem klarkomme ......schluchz! 🙂)
TPL hatte ich schon gesehen, aber noch nicht gelesen.
Die Notwendigkeit der Prüfung des Invoke habe ich unterlassen, da das Ergebnis auf jeden Fall true ist. Auslesen aus 'nem DGV geht ohne, einschreiben nur mit.
Ich wollte eigentlich, dass das Dgv seine zeilen aktuell bekommt - als eine Art deutlich sichtbarem Fortschrittsbalken. Mit Thread(newThreadStart()) funktionierte es, deswegen war ich überrascht, dass es bei Task nicht läuft.
Und jetzt werde ich lesen...
Bedankt nochmal!
Hallo,
in meinem Programm erstelle ich einen Task, der in einer Unterklasse längere Aktionen ausführen soll: Webabrufe, Umwandlunge u.ä.
Die Ergebnisse soll das Programm mithilfs Invoke in ein DataGridView schreiben.
SubClass scl = new SubClass()
{
dgv = MeineTabelle
};
Task<string> task = Task.Factory.StartNew(scl.Tuwat);
if(string.IsNullOrEmpty(task.Result) return;
// Weiteres in der Hauptklasse
// in der Unterklasse scl:
void string Tuwat()
{
for (int i...)
{
// Webabruf(e)...
dgv.Invoke(...);// delegate(...) ist korrekt, dgv wurde korrekt übergeben
}
return "xyz";
}
Am dgv.Invoke bleibt das Programm hängen, wartet... Habe ich an den Tasks etwas falsch verstanden?
Danke für Tipps und Hinweise!
hai Leute,
ich habe eine Liste/ein Array mit reichlich Einträgen. Diese Liste möchte ich nach einem Text durchsuchen, den ich in die ComboBox/TextBox eingebe.
Über das Event TextChanged startet üblicherweise die Suche. Nun möchte ich aber eben diesen Start verzögern, wenn ich mehrere Zeichen kurz nacheinander in die TextBox eingebe. Bei Windows funktioniert das gut, in meinem Programm bekomm' ich's nicht hin, da ja jede Änderung des Textes eine neue Suche in einer neuen Instanz (?) startet.
bei meiner Internetsuche hat mir der im Titel genannte Suchbegriff (oder ähnliches) nicht geholfen. Habt ihr 'nen Tipp, wonach ich suchen muss? Den passenden Code bastele ich mir dann schon.
Ich weiß eben nur nicht, wie und wo ich ansetzen muss.
Danke im Voraus, viele Grüße, ein schönes neues Jahr an alle - ...lypô
using System.Windows.Forms;
using SWF = System.Windows.Forms;
...
SWF.Timer tm2 = new SWF.Timer { Interval = 1 };
Deswegen...
Mit meinem Programm aktualisiere ich eine Webseite, d.h. ich erhalte Texte als PDF oder *.doc-Datei, das Programm formt diese passend um und lädt sie über ein dem Browser nachgebildetes Interface in eine Datenbank hoch. Das muss einwandfrei funktionieren - auch wenn's nur ein MiniJob ist, es ist 'n Job. Mit dem Backgroundworker tut's das, Aktualisierung auf Tasks dann, wenn ich mit den Task-Geschichten klar komme. Manches findet den Weg in mein Gehirn nicht so schnell. 😦 Und das ist 'ne Entschuldigung ... für mich ... vorerst.
Ich nutze den SWF-Timer. Bei den anderen muss ich mal schauen, was die bieten.
Bedankt, gehabe dich wohl - ...lypô
Ja, ich meinte System.Windows.Forms -> SWF. Mit WPF habe ich mich noch nicht beschäftigt.