Laden...
Avatar #nZo9Gyth4VPDSxGqM4sT.jpg
BerndFfm myCSharp.de - Team
Softwareentwickler Frankfurt a.M. Dabei seit 20.01.2006

Forenbeiträge von BerndFfm Ingesamt 3.833 Beiträge

08.01.2021 - 19:13 Uhr

Schau auch hier :

http://download.seven-c.de/files/DatenbankenHowTo.htm#10

Kapitel 11 "Datenbankunabhängige Programmierung"

Grüße Bernd

07.01.2021 - 16:03 Uhr

JSON wird wie folgt deserialisiert :


CustomerData customerdata = JsonConvert.DeserializeObject<CustomerData>(json);

Die Klasse CustomerData kannst Du Dir aus der JSON Datei erzeugen lassen :

https://jsonutils.com/

Grüße Bernd

29.12.2020 - 10:16 Uhr

Mit Dataset und ADO.NET wäre das einfacher als wenn Du Dir die SQL Kommandos selber zusammenbaust :


r2["binary"] = (byte[]) r["binary"];

Ich kopiere Tabellen und Spalten auch einzeln wenn ich nicht weiß ob die Strukturen der beiden Datenbanken gleich sind oder wenn die Datenbanken von verschiedenem Typ sind (Anderes DBMS als Microsoft).

Grüße Bernd

19.12.2020 - 13:28 Uhr

Bei mir sieht das so aus wenn man das Programm schließt :


mel += "Folgende Fenster sind noch geöffnet :";
foreach (Form frm in Application.OpenForms)
	mel += "\r\n" + frm.Text + " : " + frm.Name;

Grüße Bernd

17.12.2020 - 12:39 Uhr

Eine Berechtigung kann eine Software nicht einrichten. Wenn das ginge bräuchte man keine Berechtigungen.

Das muss immer der Adminstrator der IT einrichten.

Man kann Schreib- und Lesevorgänge immer in einen try-catch Block packen, dann bekommt man immer aussagekräftige Fehlermeldungen.

Grüße Bernd

16.12.2020 - 12:21 Uhr

Ich kenne nur den Unterschied zwischen Advertised und Non Advertised Shortcuts.

Vielleicht hat das was damit zu tun.

Advertised Shortcuts kann man nachträglich nicht ändern.

Auswahl eines Setup-Programmes für die eigene Applikation

Grüße Bernd

16.12.2020 - 12:09 Uhr

Das funktioniert nur wenn genau ein Benutzer an der Datenbank angemeldet ist.

Wenn mehrere Benutzer angemeldet sind und gleichzeitig Daten erfassen ist das schwieriger.

Grüße Bernd

14.12.2020 - 13:51 Uhr

Das steht in der Dokumentation zu StreamWriter :


 using (StreamWriter sw = new StreamWriter(file, false, Encoding.UTF8)) ...

Grüße Bernd

14.12.2020 - 10:23 Uhr

"Normal" gibt es nicht.

Die Umlaute sind Sonderzeichen und werden kodiert. Dafür gibt es verschiedene Zeichensätze. Die kann man im StreamWriter angeben.

Es gibt :


Encoding.GetEncoding(850)                     // MS-DOS ASCII Zeichensatz
Encoding.GetEncoding(1252)                   // Windows ANSI Zeichensatz
Encoding.UTF8                               // Universeller Zeichensatz, Standard bei .NET

Grüße Bernd

10.12.2020 - 11:47 Uhr

Ich benutze den eingebauten Compiler.

Assemblies muss man alle hinzufügen, das muss man selber machen.

Man kann angeblich auch VB, F#, Javascript und C++ übersetzen und ausführen, klappt bei mir aber noch nicht alles.

CSharpCodeProvider codeProvider = new CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v3.5" } });
ICodeCompiler icc = codeProvider.CreateCompiler();
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("System.dll");
...
parameters.GenerateInMemory = true;
parameters.GenerateExecutable = true;
parameters.IncludeDebugInformation = false;
CompilerResults results = icc.CompileAssemblyFromSource(parameters, source);
if (results.Errors.Count > 0) ...
...
MethodInfo main = null;
Object[] args = null;
main = program.GetMethod("ListeAusgeben");
args = new Object[] { qdb, ds };
main.Invoke(null, args);

Grüße Bernd

PS.: CreateCompiler() sollte nicht mehr benutzt werden.

09.12.2020 - 12:47 Uhr

Ich mache das so, speichere den Sourcecode aber in der Datenbank in einer Textspalte.

Die Anwender können sich selber Scripts in C# oder Visual Basic schreiben und an bestimmten Stellen ausführen lassen.

Dazu gibt es verschiedene Vorlagen für verschiedene Zwecke.

Grüße Bernd

16.11.2020 - 18:13 Uhr

Ich hatte nicht gesehen dass es eine ViewRow ist.

Der Fehler besagt dass die Zeile im Dataset nicht mehr in der Datenbank gefunden wurde.

Sie wurde z.B. inzwischen von einem anderen Benutzer geändert.

Ich hatte den Fehler mal bei MySQL weil dort Zahlen falsch gerundet wurden und so der CommandBuilder die Zeile nicht mehr gefunden hat.

Lösung : Parallelitätsverletzung

Im Zweifel die SQL Kommandos anschauen und eventuell selber schreiben.

Grüße Bernd

16.11.2020 - 09:59 Uhr

foreach (DataGridViewRow row in dGV_main.SelectedRows) row.Delete();
this.TA.Update(this.DS.Leuchten);

RemoveAt löscht die Zeile aus dem DataSet, also wird sie nicht in der Datenbank gelöscht oder geändert.

Der Code kann so nicht funktioniert haben weil Du eine Zeile auf "Deleted" setzt die Du vorher entfernt hast. Das geht nicht.

Grüße Bernd

13.11.2020 - 13:21 Uhr

RemoveAt(row.Index) löscht die Zeile aus dem DataSet im Speicher und ändert nichts in der Datenbank.

Damit die Zeile in der Datenbank gelöscht wird musst Du die Zeile im DataSet als Gelöscht markieren, mit Update() wird dann die Zeile in der Datenbank gelöscht.

Zeile in der Datenbank löschen : row.Delete()

Grüße Bernd

09.11.2020 - 19:47 Uhr

Hört sich nach UPS an.

Ich habe eine Tabelle Zonen und eine Tabelle Tarife.

Die kann man aus den UPS Dateien importieren.

Grüße Bernd

29.10.2020 - 11:42 Uhr
for (int i = 0; i < 16; i++) liste[i] = rand.Next(1, 6);

pictureBox1.Image = GetImage(liste[0]);
pictureBox2.Image = GetImage(liste[1]);
pictureBox3.Image = GetImage(liste[2]);
...


private Image GetImage(int nr)
{
    if (nr == 1) return Properties.Resources.banana;
    if (nr == 2) return Properties.Resources.cherry;
    if (nr == 3) return Properties.Resources.grapes;
    if (nr == 4) return Properties.Resources.orange;
    if (nr == 5) return Properties.Resources.seven;
    return null;
}

Mehr kann ich nicht schreiben sonst habe ich das fertig programmiert.

Wir wissen immer noch nicht was denn genau nicht funktioniert.

Mach die Bilder mal als Anhang an den Beitrag wie es gedacht ist.

Grüße Bernd

29.10.2020 - 10:12 Uhr

Die Zuordnung der Pictureboxen an das Array finde ich sehr unglücklich.

Was passiert wenn Du das nur einmal machst am Anfang in Form1_Load() ?

Was passiert wenn Du das Image direkt pictureBox1 zuordnest ?

Ich würde nur mit einem Array bzw. List <> arbeiten.

Alternativ ohne Array :

pictureBox1.Image = GetImage(liste[0]);
pictureBox2.Image = GetImage(liste[1]);
pictureBox3.Image = GetImage(liste[2]);
...

Grüße Bernd

29.10.2020 - 08:13 Uhr

Deine Graphiken oben kann man nicht sehen, da sie auf privat stehen.

liste(x) kann doch nur 1 bis 5 beinhalten ?

Dann könntest Du dein Programm zusammenfassen zu :


linie = 0;
if (liste[1] == liste[2] && liste[1] == liste[3] && liste[1] == liste[4]) line = 1;
if (liste[5] == liste[6] && liste[5] == liste[7] && liste[5] == liste[8]) line = 2;
if (liste[9] == liste[10] && liste[9] == liste[11] && liste[9] == liste[12]) line = 3;
if (linie > 0) ...

Grüße Bernd

28.10.2020 - 15:17 Uhr

In ArrayFuellen wird nichts besonderes gemacht, auch keine Events abonniert.

Ich muss das mal genau analysieren wenn ich mehr Zeit habe.

Ich werde berichten.

Grüße Bernd

...
	Liste.VirtualMode = true;
	Liste.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(Liste_RetrieveVirtualItem);
	Liste.VirtualListSize = anzzeilen;
...

private ArrayFuellen()
{
    int m = 0;
    foreach(row ...)
    {
        ListViewItem lvItem = new ListViewItem(inhalt);
        for (int i = 1; i < anzspal; i++)
        {
            lvItem.SubItems.Add(...);
        }
        adr[m] = lvItem;
        m++;
    }
}
						
private void Liste_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
    if (adr[e.ItemIndex] != null)
        e.Item = adr[e.ItemIndex];
    else
    {
        e.Item = new ListViewItem("");
        for (int i = 1; i < anzspal; i++) e.Item.SubItems.Add("");
    }
}

27.10.2020 - 11:53 Uhr

Die Anzeige erfolgt mit einem ListView im VirtualMode.

Das ist WinForms.

Grüße Bernd

27.10.2020 - 09:15 Uhr

Nein, noch nicht.

Habe erstmal Quick and Dirty eine Meldung ins Programm eingebaut dass man das Programm neu starten soll wenn mehr als 1000 MB belegt sind.

Ich werde berichten.

Grüße Bernd

23.10.2020 - 12:24 Uhr

Meiner Meinung nach sind alle Referenzen entfernt.

Aber das ist ein guter Hinweis, werde ich mal genau untersuchen.

Grüße Bernd

23.10.2020 - 11:00 Uhr

Hallo,

ich bin jetzt auf einen Fehler in meinen Applikationen gestoßen nachdem 2 Kunden öfter einen Memory Overflow hatten. Alle Protokolle haben nichts ausgesagt.

Jetzt habe ich festgestellt dass es durch Arrays / Lists kommt deren Speicher nicht freigegeben wird.

Hintergrund : Vor langer Zeit habe ich nach einer Möglichkeit gesucht um Bildschirmlisten mit großen Datenmengen sehr schnell anzuzeigen. Etwas Fertiges gab es damals nicht, deshalb habe ich das wie folgt selber gebaut :

Virtuelles ListView, es werden die ersten 30 Zeilen angezeigt, dann wird "Fertig" vorgegaukelt. In einem eigenen Thread wird im Hintergrund ein Array mit den Items gefüllt. Die Zeilen werden nur hergestellt wenn man tatsächlich hinblättert (Lazy Loading).
So wird eine Liste mit über eine Millionen Datensätzen in einer Sekunde angezeigt.
Nur wenn man nach einer Spalte sortiert dauert es länger.

Die ListViewItems speichere ich in einem Array, das ist der Klasse als private definiert ist.

private ListViewItem[] adr;

private void InitList()
{
    adr = new ListViewItem[anzzeilen];
    Thread t = new Thread(ArrayFuellen);
    t.Start();
}

Auch nach Beenden der Klasse und Dispose bleibt der Speicher durch das Array belegt. Auch wenn der Thread beendet wird.

Auch ein Umbau auf List<> ergibt keine Änderung.

Alle Bordmittel von .NET schlagen fehl, der Speicher bleibt auf jeden Fall belegt.

Übrigens : Ist .NET 3.5.

Welche Möglichkeiten gibt es den Speichern freizugeben ?

Oder mehrere ListViewItems so zu speichern dass der Speicher wieder freigegeben wird ?

Grüße Bernd

15.10.2020 - 09:07 Uhr

Ich benutze über all die Funktastatur und -Maus von Cherry, die kosten zusammen so 30 Euro. Dazu Eneloop Akkus, die sind 2000 mal aufladbar.

Bisher noch keine Ausfälle.

Grüße Bernd

14.10.2020 - 09:38 Uhr

So ganz verstehe ich die Frage nicht.

"if" kennst Du und Dateiendung abfragen geht zum Beispiel mit filename.ToLower().EndsWith(".jpg").

Es gibt außerdem "Path.GetExtension()".

Deine Schleife geht einfacher mit "foreach".

Hinweis : Der OpenFileDialog ändert das Arbeitsverzeichnis wenn man das Verzeichnis wechselt.
Das am besten wieder herstellen.

string verz = Environment.CurrentDirectory;
OpenFileDialog ...
Environment.CurrentDirectory = verz;

Grüße Bernd

10.10.2020 - 21:12 Uhr

Wenn die 10 GB reichen nimm SQL Server Express Edition.

Wenn Du mehr Speicher brauchst dann MariaDB, MySQL oder PostgreSQL.

Ist alles kostenlos und es gibt Unterstützung für .NET.

Grüße Bernd

09.10.2020 - 15:10 Uhr

Variable mit mehreren string ist ein array of string :


string[] namen = new string[] { "Hans", "Egon" };
if (namen.Contains("Hans")) ...

Besser nimmst Du eine Liste.


List<string> namen = new List<string> { "Hans", "Egon" };
if (namen.Contains("Hans")) ...

Grüße Bernd

07.10.2020 - 15:00 Uhr

Du schreibst ja schon dass es nur bei Koordinaten kleiner 0 auftritt.

Die musst Du sicher extra abfangen.

Es ist normal das die Koordinaten negativ sind wenn der Sekundäre Monitor über oder links vom primären Monitor ist.

Grüße Bernd

03.10.2020 - 21:28 Uhr

PostgreSQL : .Net Support ist gut, läuft gut und stabil.

Ist bei mir viel langsamer als MySQL und MS SQL.

Grüße Bernd

30.09.2020 - 15:18 Uhr

Ich sehe in den ganzen Namensänderungen überhaupt keinen Sinn. Es hilft keinem einzigen Menschen.

Man müsste ja nicht nur Master/Slave umbenennen, sondern auch :

  • Blacklist
  • Whitelist
  • Schwarz ärgern
  • Schwarzfahrer
  • Schwarzweiß sehen
  • Schwarze
  • Rasse
  • Rasseunruhen

Und viele mehr

Grüße Bernd

16.09.2020 - 09:55 Uhr

Habs grade mal getestet :

YouTube läuft auf der IE Engine gepimpt auf Version 11, aber ruckeliger als auf der Chromium Engine.

Auch weniger Farben.

Grüße Bernd

15.09.2020 - 19:43 Uhr

T-Virus : Ich benutze beides um Google Maps anzuzeigen.

Ich werde wohl aber bald ganz auf das Chrome Control umsteigen.

Grüße Bernd

15.09.2020 - 19:14 Uhr

Man kann das Web Browser Control auf die aktuelle Version pimpen :

https://stackoverflow.com/questions/17922308/use-latest-version-of-internet-explorer-in-the-webbrowser-control

Man kann auch ein auf Chrome basierendes Control benutzen :

https://www.telerik.com/support/kb/winforms/details/how-to-embed-chrome-browser-in-a-winforms-application

Hab beides schon probiert, hat beides gut funktioniert.

Grüße Bernd

05.09.2020 - 20:23 Uhr

MySQL bzw. jetzt MariaDB ist schlank und kann sehr schnell lesen. Es wird bei fast allen Web Anwendungen benutzt.

Für meine Warenwirtschaft setze ich MS SQL und MariaDB ein. Für den Anwender ist es egal, er sieht keine Unterschiede. Geschwindigkeit ist auch gleich.

Maria DB hat keine eingebaute Funktionen für Datenbank Backup. Das muss immer ein Admin einrichten.

Ein kleiner Vergleich (fast aktuell) :

http://download.seven-c.de/files/DatenbankenHowTo.htm#10

Grüße Bernd

02.09.2020 - 10:46 Uhr

Das WebBrowser Control ist so alt dass nicht mal Google Maps funktioniert.

So kann man es pimpen : https://stackoverflow.com/questions/17922308/use-latest-version-of-internet-explorer-in-the-webbrowser-control

Ich würde die Dateien in einem ListView oder als Baumstruktur in einem TreeView darstellen.

Grüße Bernd

13.08.2020 - 13:24 Uhr

Eine Liste kannst Du wie folgt drucken :

  1. Das Control drucken :
public void PrintControl(Control pCtrl, string pPrinterName)
{
	PrintDocument doc = new PrintDocument();
	if (pPrinterName != null && pPrinterName != string.Empty)
	{
		doc.PrinterSettings.PrinterName = pPrinterName;
	}
	doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);
...
  1. Eine Liste im Reportbuilder erstellen und diese drucken :
ReportViewer reportViewer1 = new ReportViewer();
reportViewer1.ProcessingMode = ProcessingMode.Local;
...

  1. Eine Liste selber bauen :
PrintPreviewDialog dlg = new PrintPreviewDialog();
dlg.WindowState = FormWindowState.Maximized;
dlg.Name = "... Liste";
dlg.Document = printDocument1;
dlg.ShowDialog();
dlg.Dispose();

Ich würde Variante 2 nehmen.

Das Snippet von TH69 erwähnt sieht recht gut aus. Schwierig wird es nur wenn eine Liste länger als eine Seite ist. Das musst Du dann selber programmieren.

Grüße Bernd

03.08.2020 - 15:28 Uhr

Hat der Monitor 4K Auflösung ?

Bei 4K werden die Steuerelemente meistens vergrößert dargestellt.

Das Verhalten hat sich bei den Windows 10 Updates geändert.

Könnte auch an einem Update des Graphikkartentreibers liegen.

Grüße Bernd

31.07.2020 - 10:24 Uhr

Hallo,

args[0] ist der Name der Anwendung selber.

Nein. Nicht in C#/.NET.

Gruß, MarsStein

Tatsächlich ! Wo hatte ich das nur wieder her ?

Grüße Bernd

30.07.2020 - 11:54 Uhr

Besser so (ungetestet) :


foreach(string arg in args)
{
    if (arg.ToLower() == "/a")  Console.WriteLine("/a gewählt");
    if (arg.ToLower() == "/b")  Console.WriteLine("/b gewählt");
    if (arg.ToLower() == "/c")  Console.WriteLine("/c gewählt");
}

args[0] ist der Name der Anwendung selber.

Grüße Bernd

24.06.2020 - 15:47 Uhr

Ich mache es so dass jede Aktion, die länger als eine Sekunde braucht, einen Warte-Hinweis bekommt (Splash-Screen).

Am einfachsten geht das mit einem Label, das man temporär erzeugt :


Label lbl = new Label();
lbl.Size = new Size(300, 120);
lbl.Location = new Point(parentcontrol.Width / 2 - lbl.Width / 2, parentcontrol.Height / 2 - lbl.Height / 2);
lbl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
lbl.Text = "        " + message + "       ";
lbl.BorderStyle = BorderStyle.FixedSingle;
parentcontrol.Controls.Add(lbl);
lbl.BringToFront();

Wenn man eine Fortschrittsanzeige anzeigt unbedingt asynchron arbeiten, wie oben schon erwähnt.

Auch eine Funktion für "Abbrechen" vorsehen.

Gehört für mich alles zu einer guten App.

Ich ärgere mich selber immer sehr wenn ich auf einem Button rumklicke und nichts passiert.

Hab deshalb in einem Web-Shop das tiefgefrorene Hundefutter 3 Mal bestellt, weil nach dem Klick nichts passiert ist. Zum Glück hatte ich genug Platz in der Tiefkühltruhe.

Grüße Bernd

03.06.2020 - 15:41 Uhr

Für das Kopieren von Dateien und das Synchronisieren von Verzeichnissen in eine Cloud mit SFTP benutze ich übrigens einen C# Wrapper für WinSCP. Klappt wunderbar. Es klappt auch ein Sync mit 100.000 Dateien.

Grüße Bernd

03.06.2020 - 14:16 Uhr

Danke für Deine Tipps.

Free File Sync ist ein guter Tipp. Syncthing sieht auch gut aus.

Für beide gibt es Steuerung über URL bzw. Command Line. Das könnte ich dann ansteuern.

Das ist auf jeden Fall sicherer als selber einen Port nach außen zu öffnen.

Grüße Bernd

02.06.2020 - 14:35 Uhr

Ich würde Dir empfehlen ein ORM oder Micro-ORM einzusetzen.

Bei mir würde deine Routine z.B. so aussehen :


foreach (DataObjectsArtikel ar in new DataCollectionArtikel(qry))
{
    ArtikellisteIndex = ar.rowindex;
    ArtikelNummer = ar.nr;
    ArtikelName = ar.name;
    BestellMenge = ar.bestmenge;
    Geliefert = ar.geliefert;
    PrioMenge = ar.priomenge;
    Datum = ar.datum;
}

Alles typsicher und mit richtiger Umwandlung.

Grüße Bernd

02.06.2020 - 10:01 Uhr

Hallo,

ich möchte gerne sehr große Dateien (10 - 100 GB) übers Internet übertragen von Arbeitsplatz zu Arbeitsplatz.

Welches Protokoll bzw. welche Technologie würdet ihr empfehlen ?

Bisher habe ich einfach einen TcpClient aufgemacht und per TcpListener empfangen.

Ist so ein TcpListener offen im Internet gefährlich ?

Kann man sowas sicher machen ohne Server in der Mitte ? Oder muss man dafür einen Dienst (Cloudflare, Azure) einsetzen ? Firewall mit DMZ kann ich leider nicht voraussetzen, FritzBox mit freigegebenem NAS Laufwerk schon.

Verschlüsselung wäre schön, muss aber nicht sein.

Resume bei Abbruch muss sein, das würde ich aber auch selber programmieren.

Die Rechner sind nicht immer eingeschaltet.

Grüße Bernd

PS.: Nein, ich möchte keinen Filesharing-Server oder Cloudflare-Konkurrenz programmieren 😉

02.06.2020 - 09:52 Uhr

Wenn es im Style nicht geht muss man es selber machen (wie so oft in .NET) :

Spaltenbreiten merken und wenn die Schrift kleiner wird selbst kleiner machen. ich mache das bei einer ListView bei WinForms so.

Grüße Bernd

28.05.2020 - 12:21 Uhr

Daten im Web kannst Du abrufen mit :


WebClient cl = new WebClient();
string html = cl.DownloadString(...);
...

Wenn die Website ohne Browser nichts liefert kannst Du ein WebBrowser Control einsetzen, die Website laden und dann das aktuelle Dokument auslesen.

Grüße Bernd

27.05.2020 - 09:03 Uhr

Alle Dateien einlesen :

string[] files = Directory.GetFiles(path, "*.csv", ...);

Statt "c:\users..\documents" kann man Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) benutzen.

Grüße Bernd

26.05.2020 - 11:26 Uhr

Nächster Tag 14 Uhr geht auch eventuell mit der .Date() Methode :


EndZeit = StartZeit.Date().AddDays(1).AddHours(14);

Abt : Ich mache das schon immer so dass die Applikation auf dem freigegebenen Netzwerklaufwerk liegt und das klappt immer noch super. Auch ein Update im laufenden Betrieb klappt.
Ich habe bisher keine Nachteile damit gehabt.

Ist eher Geschmacksache wie man das macht.

Ich mache das mit den Updates anders :
Ich kompiliere 5 Versionen mit den Namen App1.exe bis App5.exe. Ich installiere alle 5, aber nur die die nicht gesperrt sind. Per Programmlauncher starte ich immer die neueste Version dieser 5 Apps.

Ich muss die 5 Versionen einzelnen kompilieren da ich TxtControl verwende und das erlaubt die Umbenennung einer Exe nicht. Warum auch immer.

Grüße Bernd

20.05.2020 - 09:21 Uhr

Für neue Entwicklungen super interessant !

Ich habe schon mit Mono und Linux gearbeitet und probiere mich gerade an xamarin.forms.

Das sind noch Verbesserungen notwendig, z.B. WYSIWYG Designer.

Grüße Bernd

19.05.2020 - 09:13 Uhr

Oder den bösen Befehl Sleep :

Thread.Sleep(random.Next(300, 3000));

Grüße Bernd