Laden...
A
AceTecNic myCSharp.de - Member
Feinwerkmechanikermeister Bayern Dabei seit 23.02.2018 51 Beiträge
Benutzerbeschreibung

Forenbeiträge von AceTecNic Ingesamt 51 Beiträge

13.10.2023 - 07:23 Uhr

Guten Morgen zusammen und dankeschön für die Rückmeldungen!

Die Variante mit dem auslagern in einen extra Thread gefällt mir recht gut. Da der Prüfvorgang mit 60 Sekunden + Wartezeit auf Bedingung (Erreichen des Startwertes) sowieso als längere Aufgabe zählt, werde ich das versuchen so umzusetzen.

Eventuell könnte mir noch jemand einen Tipp geben, wie ich verhindern kann, dass der "Backgroundworker" nicht sofort seine Arbeit beendet?

Ich starte ihn mit einem Button und dieser sollte dann eben in die while-Schleife gehen bis ich den bool zeitVorbei==true setze.

Allerdings wird die Schleife gar nicht erst aufgerufen... Hab ich was übersehen?

Codeschnipsel:

private void InitializeBackgroundWorker()
        {
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += BackgroundWorker_Arbeit;
            backgroundWorker.RunWorkerCompleted += BackgroundWorker_WorkerFertig;
            backgroundWorker.ProgressChanged += BackgroundWorker_Fortschritt;
            backgroundWorker.WorkerReportsProgress = true;
        }

        private void StartBackgroundWorkButton_Click(object sender, EventArgs e)
        {
            if (!backgroundWorker.IsBusy)
            {
                // Starte den BackgroundWorker.
                backgroundWorker.RunWorkerAsync();
            }
        }

        private void BackgroundWorker_Arbeit(object sender, DoWorkEventArgs e)
        {
            while (zeitVorbei == false)
            {
                // Diese Methode wird im Hintergrund ausgeführt.
                Console.WriteLine("Worker aktiv");
                if (this.druckkraft_ist < this.startDruck)
                {
                    Console.WriteLine("Schleife klein aktiv");


                }

                if (this.druckkraft_ist > this.startDruck)
                {
                    Console.WriteLine("Schleife groß aktiv");
                    for (int i = 0; i <= 100; i++)
                    {
                        picbox_Klartextanzeige.BackColor = Color.Lime;
                        lbl_Klartextanzeige.BackColor = Color.Lime;
                        lbl_Klartextanzeige.Text = "   Druck erhöhen auf " + this.variablenSpeicher.Druckkraft + " kN\n" + "  Startdruck ist " + this.startDruck + " kN";



                        if (this.druckkraft_ist > this.startDruck)
                        {


                            if (this.druckkraft_ist > druckKraft)
                            {
                                picbox_Klartextanzeige.BackColor = Color.YellowGreen;
                                lbl_Klartextanzeige.BackColor = Color.YellowGreen;
                                lbl_Klartextanzeige.Text = "Druck erhöhen auf " + this.überDruck + " kN";
                            }

                        }
                        backgroundWorker.ReportProgress(i);
                    }
                }

                else
                {
                    Console.WriteLine("Nichts");
                }
                //Thread.Sleep(333);
            }
        }

        private void BackgroundWorker_Fortschritt(object sender, ProgressChangedEventArgs e)
        {
            // Diese Methode wird aufgerufen, wenn der BackgroundWorker den Fortschritt meldet.
            progbar_Prüfzeit.Value = e.ProgressPercentage;
        }

        private void BackgroundWorker_WorkerFertig(object sender, RunWorkerCompletedEventArgs e)
        {
            // Diese Methode wird aufgerufen, wenn der BackgroundWorker seine Arbeit beendet hat.
            if (e.Error != null)
            {
                // Wenn während des Hintergrundprozesses ein Fehler aufgetreten ist.
                MessageBox.Show("Fehler aufgetreten: " + e.Error.Message);
            }
            else
            {
                // Wenn die Aufgabe erfolgreich abgeschlossen wurde, aktualisiere das Label.
                picbox_Klartextanzeige.BackColor = Color.Red;
                lbl_Klartextanzeige.BackColor = Color.Red;
                lbl_Klartextanzeige.Text = "         Prüfung beendet";
            }
        }
09.10.2023 - 15:16 Uhr

Okey danke für die Info! Dann werde ich mich mal damit auseinander setzen und die Methode in einem extra Thread laufen lassen.

Dankeschön! 😃

09.10.2023 - 11:39 Uhr

Hallo Zusammen,

Benötige wieder einen Denkanstoß

Soll:

Über einen Button wird die "Prüfung" gestartet. Anschließend muss der Anwender eine Maschine Bedienen um den Messwert zu erhöhen. Eine Progressbar soll nach dem erreichen des Startwertes (50) 60s lang laufen. Die Messwerte (3 Werte / Sekunde) werden aufgezeichnet und in einem Graph ausgegeben.

Problem:

Nach dem Klick auf den Button wird der Code darin nicht mehr ausgeführt. Mit einer While-Schleife lege ich auch alles Lahm. Das Pgm soll weiterlaufen. Dabei soll aber auf die Bedingung (Startwert) "gewartet" werden und anschließend weiterer Code ausgeführt werden.

Vielleicht kann mir ja jemand einen Tipp geben, wie ich das angehen kann? 😃

Dankeschön!

10.07.2023 - 19:06 Uhr

Hirnknoten gelöst. Vielen Dank!!!

Alter Codeschnipsel:

private Variablenspeicher variablenSpeicher;

Neuer Codeschnipsel:

private Variablenspeicher variablenSpeicher = new Variablenspeicher();
10.07.2023 - 16:13 Uhr

Hallo Zusammen,

Ich hänge gerade etwas fest...

Ich möchte in der Variablenspeicher.cs den String 500 fest hinterlegen und bei Bedarf über Einstellungen.cs ändern. (Nur für die Laufzeit des PGM)

Beim übernehmen bekomme ich die Fehlermeldung "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt".

Kann mir jemand einen Tipp geben? 😃

Einstellungen.cs:

namespace Keilprüfprogramm
{
    public partial class Einstellungen : Form
    {

        private Variablenspeicher variablenSpeicher;
        private string startWert;



        public Einstellungen()
        {
            InitializeComponent();
        }

        private void übernehmenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.startWert = txtin_Startwert.Text;
            this.variablenSpeicher.StartDruck = this.startWert.ToString(); //<-- Fehlerstelle
        }

        private void Einstellungen_Load(object sender, EventArgs e)
        {
            try
            {
                startWert = variablenSpeicher.StartDruck;
                txtin_Startwert.Text = startWert;
            }
            catch
            {
                this.txtin_Startwert.Text = "550";
            }

        }

        private void abbrechenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}

Variablenspeicher.cs:

namespace Keilprüfprogramm
{
    /// <summary>
    /// Datenspeicherklasse für alle Variablen
    /// </summary>

    class Variablenspeicher
    {
        private string portName = "COM3";
        private int baudRate = 115200;
        private string vorname;
        private string nachname;
        private string startDruck = "500";


        }

        public string StartDruck { get => startDruck; set => startDruck = value; }
    }
}
27.02.2023 - 13:55 Uhr

Vielen Dank Abt! Habe das ganze mit BeginInvoke gemacht und es funktioniert wesentlich besser! Top 🙂

Wilfried: Das funktioniert soweit ganz gut. Warten tut da eigentlich nichts, wenn dann im µSekunden Bereich. Aber für meine drei Messungen/Sekunde reicht das ;D
Danke!

24.02.2023 - 15:20 Uhr

Würde mir bitte jemand erklären, wie man ein Event(?) beendet um den Serial.Port ordnungsgemäß zu schließen?

Ich öffne den Port, und bei eingehenden Daten startet DataReceivedHandler. Wenn ich nun btn_PortAbbrechen klicke, sollte dieser ja normalerweise schließen. Das funktionierte bisher relativ gut. Gelegentlich ist das Programm eingefroren allerdings.

Das hier sind Code-Schnipsel, der komplette Code wäre wohl nur unnütz lang:


using System;
using System.IO.Ports;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Drawing;

namespace Schmid_Prüfprogramm
{
    public partial class Schmid_PP : Form
    {
        SerialPort SerialPort = new SerialPort();
        private delegate void threadSicher(string messung);

        //Private Variablen ----------------------------------------------------------------------------------------------------------
        string portName;
        int baudRate = 19200;


        public Schmid_PP()
        {
            //Funktionen die beim Start ausgeführt werden sollen hier rein.
            InitializeComponent();
            fillComPortComBoBox();
            dateTimePicker1.Value = DateTime.Now;
            btnLED_ReferenzStatus.BackColor = Color.Red;

        }

                private void btn_portVerbinden_Click(object sender, EventArgs e)
        {
            try
            {
                SerialPort.PortName = combox_Portliste.SelectedItem.ToString();
                SerialPort.BaudRate = baudRate;
                SerialPort.Open();
                SerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                Console.WriteLine("Port geöffnet");
                btn_portVerbinden.Enabled = false;
            }
            catch (Exception)
            {
                MessageBox.Show("Keinen Port ausgewählt", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btn_PortAbbrechen_Click(object sender, EventArgs e)
        {
            SerialPort.Close();
            
            lbl_Anzeige.Text = "N.A.";
            lbl_Temperatur.Text = "N.A.";
            btn_portVerbinden.Enabled = true;
        }

        public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            //Console.WriteLine("Daten werden empfangen");
            SerialPort serialPort = (SerialPort)sender;
            string indata = serialPort.ReadLine();
            updateMessung(indata);
        }

        private void updateMessung(string indata)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new threadSicher(updateMessung), new object[] { indata });
            }
        }
    }
}

Ich denke, das nötigste ist mit drin.

23.02.2023 - 11:43 Uhr

Vielen Dank!

Genau das war mein Fehler. Jetzt funktioniert das ganze wie es soll 😁

Dankeschön!!

23.02.2023 - 11:04 Uhr

Hallo zusammen,

In meiner Anwendung soll die Zeit gestoppt werden, solange eine Lichtschranke aktiv und ein RadioButton gecheckt ist. Solange die Lichtschranke inaktiv ist, soll die Stopwatch pausiert werden und bei Aktivierung wieder weiter laufen. Die Verstrichene Zeit wird ausgegeben wenn die Lichtschranke inaktiv ist. (Alternativ wollte ich das erst anzeigen lassen wenn beispielsweise Messung2 gecheckt wird, aber das ist egal...)

Mein Problem: Die Zeitmessung wird nicht gemacht. Es wird immer nur 00 angezeigt und ich weiß leider echt nicht warum... Hat mir jemand einen Tipp?

Hier meine Funktion in der das ganze geschehen soll:
(Aktuell habe ich natürlich nur die messung1 im Test, später ist das ja nur noch C&P)


        private void updateMessung(string indata)
        {
            
            if (this.InvokeRequired)
            {
                this.Invoke(new threadSicher(updateMessung), new object[] { indata });
            }

            Console.WriteLine("Update Messung gestartet");

            //Ab hier Code der laufen soll sobald der COM-Port verbunden ist und Daten empfängt --------------------------------------------------
            try
            {
                string[] arr = indata.Split('|'); //WinkelWert|Temp|Referenz|Lichtschranke <-- Daten vom Controller
                                                  //Daten werden im Array (arr) gespeichert und mit dem | getrennt. Daten können Blockweise abgerufen werden mit arr[1] arr[2] usw...
                lbl_Anzeige.Text = arr[0] + " °"; //Winkelanzeige Echtzeit

                lbl_Temperatur.Text = arr[1] + " °C"; //Temperaturanzeige        
                
                if (arr[2].Contains("OK")) //Referenzstatus
                {
                    btnLED_ReferenzStatus.BackColor = Color.Green;
                }

                string lichtSchrankeStatus = arr[3];

                //Hier Code der laufen soll wenn ein RadioButton gecheckt ist:-------------------------------------------------------------------
                if (messung1.Checked)
                {
                    Stopwatch stopwatch1 = new Stopwatch();

                    if (lichtSchrankeStatus.Contains("AN"))
                    {
                        stopwatch1.Start();
                        lbl_a011.Text = arr[0];
                    }
                    
                    
                    if (lichtSchrankeStatus.Contains("AUS"))
                    {
                        stopwatch1.Stop();
                        TimeSpan ts1 = stopwatch1.Elapsed;
                        string zeitMessung1 = String.Format("{0:00}",ts1.Seconds);
                        lbl_Zeit11.Text = zeitMessung1;
                    }
                    
                }
                
                else if (messung2.Checked)
                {
                    Timer timer2 = new Timer();
                    timer2.Start();
                    lbl_a021.Text = arr[0];
                }

                else if (messung3.Checked)
                {
                    lbl_a031.Text = arr[0];
                }

                else if (messung4.Checked)
                {
                    lbl_a012.Text = arr[0];
                }

                else if (messung5.Checked)
                {
                    lbl_a022.Text = arr[0];
                }

                else if (messung6.Checked)
                {

                    lbl_a032.Text = arr[0];
                }
            }
            catch
            {
                //Fehlerbehandlung wenn keine oder falsche Daten ankommen
                lbl_Anzeige.Text = "Lädt..";
                lbl_Temperatur.Text = "Lädt..";


                /* ---Alte Version---
                DialogResult result = MessageBox.Show("Fehler bei der Datenübertragung! Erneut versuchen?", "Fehler", MessageBoxButtons.YesNo, MessageBoxIcon.Error);

                if (result == DialogResult.Yes)
                {
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new threadSicher(updateMessung), new object[] { indata });
                    }

                }
                if (result == DialogResult.No)
                {
                    SerialPort.Close();
                    SerialPort.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler);
                    lbl_Anzeige.Text = "N.A.";
                    lbl_Temperatur.Text = "N.A.";
                    btn_portVerbinden.Enabled = true;
                }*/
            }
            

            if (rdbtnMessungBeendet1.Checked)
            {
                try
                {
                    string lblGrad1string = lbl_a011.Text;
                    string lblGrad2string = lbl_a021.Text;
                    string lblGrad3string = lbl_a031.Text;
                    decimal lblGrad1dc = Convert.ToDecimal(lblGrad1string);
                    decimal lblGrad2dc = Convert.ToDecimal(lblGrad2string);
                    decimal lblGrad3dc = Convert.ToDecimal(lblGrad3string);
                    decimal lblGradGesamt1dc = ((lblGrad1dc + lblGrad2dc + lblGrad3dc) / 3) / 10;

                    lblGradGesamt1dc = decimal.Round(lblGradGesamt1dc, 1);
                    string lblGradGesamt1String = Convert.ToString(lblGradGesamt1dc);
                    lbl_a01.Text = lblGradGesamt1String;
                }
                catch (Exception)
                {
                    rdbtnMessungBeendet1.Checked = false;
                    MessageBox.Show("Alle Messungen zuerst durchführen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);

                }

            }
            if (rdbtnMessungBeendet2.Checked)
            {
                try
                {
                    string lblGrad4string = lbl_a012.Text;
                    string lblGrad5string = lbl_a022.Text;
                    string lblGrad6string = lbl_a032.Text;
                    decimal lblGrad4dc = Convert.ToDecimal(lblGrad4string);
                    decimal lblGrad5dc = Convert.ToDecimal(lblGrad5string);
                    decimal lblGrad6dc = Convert.ToDecimal(lblGrad6string);
                    decimal lblGradGesamt2dc = ((lblGrad4dc + lblGrad5dc + lblGrad6dc) / 3) / 10;

                    lblGradGesamt2dc = decimal.Round(lblGradGesamt2dc, 1);
                    string lblGradGesamt2String = Convert.ToString(lblGradGesamt2dc);
                    lbl_a02.Text = lblGradGesamt2String;
                }

                catch
                {
                    rdbtnMessungBeendet2.Checked = false;
                    MessageBox.Show("Alle Messungen zuerst durchführen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }


        }

13.02.2023 - 15:38 Uhr

Denke ich habe schon etwas gefunden:

PictureBox einfügen;
BorderStyle = FixedSingle einstellen;

Fertig.

Danke 🙂

13.02.2023 - 15:29 Uhr

Hallo zusammen,

Ich bin auf der Suche nach einer Möglichkeit, Linien oder Rechtecke zu erstellen auf dem UI. Diese sollen natürlich rein optischen Wert haben.
Dabei bin ich auf diesen Beitrag gestoßen: [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox).
Gibt es denn auch für den Designer eine Art Addon für die Toolbox? Oder muss das über den Code erstellt werden?
Ich verwende Microsoft Visual Studio 17 | Windows Forms Anwendung.

17.01.2023 - 15:48 Uhr

Alles klar. Bedeutet für mich, dass manche Teile des Codes zwangsläufig in der UI bleiben.
Somit muss ich versuchen, von der Form2(Prüfprotokoll.cs) auf Form1(Schmid_PP.cs) zuzugreifen.

Vielleicht ist der Code nicht zu 100% richtig, aber auf irgendeine Weise funktioniert es 😁


using System;
using System.IO.Ports;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Drawing;

namespace Schmid_Prüfprogramm
{
    public partial class Schmid_PP : Form
    {

        string portName;
        int baudRate = 19200;
        SerialPort SerialPort = new SerialPort();
        private delegate void threadSicher(string messung);

        public Schmid_PP()
        {
            InitializeComponent();
            fillComPortComBoBox();    
        }

        private void btn_portVerbinden_Click(object sender, EventArgs e)
        {
            try
            {
                SerialPort.PortName = combox_Portliste.SelectedItem.ToString();
                SerialPort.BaudRate = baudRate;
                SerialPort.Open();
                SerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace, "Fehler", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
            }
        }

        private void fillComPortComBoBox()
        {
            combox_Portliste.Items.AddRange(SerialPort.GetPortNames());
            combox_Portliste.SelectedItem = portName;
        }

        public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = (SerialPort)sender;
            string indata = serialPort.ReadLine();
            updateMessung(indata);
        }

        
        
        
        private void updateMessung(string indata)
        {
            //string zeit1;

            if (this.InvokeRequired)
            {
                this.Invoke(new threadSicher(updateMessung), new object[] {indata});
            }

            string[] arr = indata.Split('|'); //winkelWert|btnStatus|timer
            lbl_Anzeige.Text = arr[0] + " °";
            //lbl_checkBTN.Text = arr[1];
            //lbl_Zeit1.Text = arr[2];

            if (messung1.Checked)
            {
                //lbl_Zeit1.Text = arr[2];
                lbl_Grad1.Text = arr[0];
            }

            else if (messung2.Checked)
            {
                //lbl_Zeit2.Text = arr[2];
                lbl_Grad2.Text = arr[0];
            }
            else if (messung3.Checked)
            {
                //lbl_Zeit3.Text = arr[2];
                lbl_Grad3.Text = arr[0];
            }
            if (messung4.Checked)
            {
                //lbl_Zeit4.Text = arr[2];
                lbl_Grad4.Text = arr[0];
            }
            if (messung5.Checked)
            {
                //lbl_Zeit5.Text = arr[2];
                lbl_Grad5.Text = arr[0];
            }
            if (messung6.Checked)
            {
                //lbl_Zeit6.Text = arr[2];
                lbl_Grad6.Text = arr[0];
            }
        }

        private void speichernToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Datenspeichernöffnen datenspeichernöffnen = new Datenspeichernöffnen(txtin_Person1.Text, txtin_Person2.Text, txtin_Person3.Text, txtin_Person4.Text, txtin_Person5.Text, txtin_Person6.Text, lbl_Zeit1.Text, lbl_Zeit2.Text, lbl_Zeit3.Text, lbl_Zeit4.Text, lbl_Zeit5.Text, lbl_Zeit6.Text, lbl_Grad1.Text, lbl_Grad2.Text, lbl_Grad3.Text, lbl_Grad4.Text, lbl_Grad5.Text, lbl_Grad6.Text);
            Datenspeichernöffnen.speichernunter(txtin_Person1.Text, txtin_Person2.Text, txtin_Person3.Text, txtin_Person4.Text, txtin_Person5.Text, txtin_Person6.Text, lbl_Zeit1.Text, lbl_Zeit2.Text, lbl_Zeit3.Text, lbl_Zeit4.Text, lbl_Zeit5.Text, lbl_Zeit6.Text, lbl_Grad1.Text, lbl_Grad2.Text, lbl_Grad3.Text, lbl_Grad4.Text, lbl_Grad5.Text, lbl_Grad6.Text);
        }

        private void btn_PortAbbrechen_Click(object sender, EventArgs e)
        {
            SerialPort.Close();
            SerialPort.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler);
            lbl_Anzeige.Text = "";
        }
        private void öffnenToolStripMenuItem_Click(object sender, EventArgs e)
        {
                using (OpenFileDialog openFileDialog = new OpenFileDialog() { Filter = "Prüfprotokoll|*.pp", Multiselect = false })
            {
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    using (StreamReader rd = new StreamReader(openFileDialog.FileName))
                    {
                        txtin_Person1.Text = rd.ReadLine();
                        lbl_Zeit1.Text = rd.ReadLine();
                        lbl_Grad1.Text = rd.ReadLine();

                        txtin_Person2.Text = rd.ReadLine();
                        lbl_Zeit2.Text = rd.ReadLine();
                        lbl_Grad2.Text = rd.ReadLine();

                        txtin_Person3.Text = rd.ReadLine();
                        lbl_Zeit3.Text = rd.ReadLine();
                        lbl_Grad3.Text = rd.ReadLine();

                        txtin_Person4.Text = rd.ReadLine();
                        lbl_Zeit4.Text = rd.ReadLine();
                        lbl_Grad4.Text = rd.ReadLine();

                        txtin_Person5.Text = rd.ReadLine();
                        lbl_Zeit5.Text = rd.ReadLine();
                        lbl_Grad5.Text = rd.ReadLine();

                        txtin_Person6.Text = rd.ReadLine();
                        lbl_Zeit6.Text = rd.ReadLine();
                        lbl_Grad6.Text = rd.ReadLine();
                    }
                }
                else
                {
                    MessageBox.Show("Konnte nicht geladen werden");
                }
            }
        }
        private void druckenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Prüfprotokoll prüfprotokoll = new Prüfprotokoll();
            prüfprotokoll.Show();

            /*if (printDialog1.ShowDialog() == DialogResult.OK)
            {
                printDocument1.Print();
            }*/
        }   
    }
}

Bevor jetzt alle drauf rumhacken: Ja der Code mag nicht perfekt sein, durcheinander und unordentlich. Trotzallem funktioniert er und ich bin stolz darauf 🙂 . Zudem bin ich noch nicht fertig damit und weiß, dass ich noch einiges vor mir habe 😉
Bin für Vorschläge immer offen.

Danke für die Hilfestellungen!

17.01.2023 - 14:57 Uhr

Ich versuchs anderst zu erklären. Ich versuche auf Grundlage von diesem Drei-Schicht-Modell mein Projekt zu bewältigen.
Jetzt habe ich aktuell auf der Präsentationsschicht das meiste von meinem Code, insbesondere diesen hier um ein Label konstant zu füttern:


private void updateMessung(string indata)
        {
            
            if (this.InvokeRequired)
            {
                this.Invoke(new threadSicher(updateMessung), new object[] {indata});
            }
            string[] arr = indata.Split('|'); //winkelWert|btnStatus|timer
            lbl_Anzeige.Text = arr[0] + " °";
          }

Wie könnte ich diesen Abschnitt denn auf die Logikschicht übertragen? Dazu benötige ich doch eine neue Klasse? Ich habe im Moment keinerlei Ansatz wie ich das Label auf der Form1 von der Logikschicht aus aktualisieren könnte.

Ich habe versucht mich möglichst genau auszudrücken. Ich bin dabei, die verlinkten Seiten durchzulesen. Allerdings übersehe ich dabei die "für mich wichtigen" Punkte, oder es ist nicht das wonach ich suche.

17.01.2023 - 14:39 Uhr

Das mit der dritten Klasse würde mir auch sehr gefallen, allerdings habe ich keine Ahnung wie ich das umsetzen soll.
Mein Problem ist auf Form1: SerialPort + Invoke welcher mir ein Label konstant aktuell hält mit einem string. Zudem werden aus dem gesendeten Daten noch zwei weitere Werte weiter verwendet.

Ist es generell möglich, aus der Helper.cs ein Control(label) auf Form1.cs zu überschreiben bzw. zu aktualisieren?

17.01.2023 - 10:37 Uhr

Hallo zusammen,

wie oben beschrieben, lasse ich eine Vorschau mit Bitmap zeichnen. Alles was sich auf dem Panel befindet, soll eben mitgezeichnet werden und ausgedruckt.
Aktuell wird allerdings nichts mit aufgezeichnet bei der Vorschau und beim Druck selbst. Fällt irgendjemanden was auf dabei?


using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;

namespace Schmid_Prüfprogramm
{
    public partial class Prüfprotokoll : Form
    {
        public Prüfprotokoll()
        {
            InitializeComponent();

            printDocument1.OriginAtMargins = true;
            printDialog1.Document = printDocument1;
            pageSetupDialog1.EnableMetric = true;
            pageSetupDialog1.Document = printDocument1;
            printPreviewDialog1.Document = printDocument1;
            /*
            Schmid_PP schmid_PP = new Schmid_PP();
            Schmid_PP.
            lbl_DruckMessung1.Text = 
            */
        }

        private void Prüfprotokoll_Load(object sender, EventArgs e)
        {

        }

        private void btnPageSetup_Click(object sender, EventArgs e)
        {
            pageSetupDialog1.ShowDialog();
        }

        private void btnPagePreview_Click(object sender, EventArgs e)
        {
            printPreviewDialog1.Top = this.Top;
            printPreviewDialog1.Width = this.Width * 2;
            printPreviewDialog1.Height = this.Height * 2;
            

            printPreviewDialog1.ShowDialog();
        }

        private void btnPrinterDialog_Click(object sender, EventArgs e)
        {
            if (printDialog1.ShowDialog() == DialogResult.OK)
            {
                printDocument1.Print();
            }
        }


        private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
        {
            Bitmap bitmap = new Bitmap(this.Width, this.Height);

            panel1.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height)); //<-- Hier sollte das Panel und die Controls darauf gezeichnet werden

            Rectangle target = new Rectangle(0, 0, e.MarginBounds.Width, e.MarginBounds.Height);
            double xScale = (double)bitmap.Width / e.MarginBounds.Width;
            double yScale = (double)bitmap.Height / e.MarginBounds.Height;

            if (xScale < yScale)
                target.Width = (int)(xScale * target.Width / yScale);
            else
                target.Height = (int)(yScale * target.Height / xScale);

            e.Graphics.PageUnit = GraphicsUnit.Display;

            e.Graphics.DrawImage(bitmap, target);
        }
    }
}

Noch eine kleine Frage am Rande:
Wenn ich Daten von einer anderen Form auf diese übertragen möchte, wie stell ich das am besten an?
Dachte mir bereits: Daten aus Form1 temporär in C:\tmp ablegen und in Form2_load wieder laden.
Macht man das so oder gibt es einen einfacheren Weg?

Danke!

16.01.2023 - 10:44 Uhr

Moin,

Moin, Bist du zufällig der TriB aus dem Arduino-Forum? 😁 😁

Ich habe das jetzt ähnlich gemacht:
Der Controller sendet an den SP Zeilenweise
a: winkelVariable
b: btnStatus

C# Code:


        private void updateMessung(string indata)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new threadSicher(updateMessung), new object[] {indata});
            }

            switch (indata)
            {
                case string a when a.Contains("a"):
                    //Console.WriteLine("a gefunden");
                    lbl_Anzeige.Text = a;
                    break;
                case string b when b.Contains("b"):
                    //Console.WriteLine("b gefunden");
                    lbl_Grad1.Text = b;
                    break;

            }
        }

Wobei die Zeile 16 nur Testhalber drin steht aktuell.

Was mich noch stört ist, dass der indentifier noch mit dran hängt.

13.01.2023 - 14:41 Uhr

Du meinst "an den SerialPort übermittle"!?

Ja genau also vom MC an SerialPort (zur Weiterverarbeitung mit C#).

Wenn du mit Werten (gemessene Grade) Zahlen im Textformat meinst, dann reicht wahrscheinlich eine der TryParse-Methoden (z.B. für Double).

den Wert(string) vom Winkelmesser habe ich ja. Prinzipiell würde ich den Status von einem Knopf(Totmannschalter) noch benötigen - den könnte ich aber auch als string/int übergeben und im Programm mit bsp.: if(zustandKnopf == 1) abfragen? Das würde mit dem Parser funktionieren? Die StateMachine zu bauen ist schon ein gewaltiger Akt (für mich), evtl geht das Parsen einfacher 😁

Dann bleibt mir noch die Frage wie ich das später mit den zwei anderen Werten (string/int) löse die ich von C# an den MC übertragen möchte. Aber um das kümmere ich mich sobald alles andere Funktioniert 😉

13.01.2023 - 13:49 Uhr

Das mit der Stopwatch hab ich gleich eingebaut, funktioniert ja sehr simpel dankeschön! 😁

Jetzt habe ich mich bezüglich der StateMachine etwas eingelesen bzw. etwas gefunden. Ich habe die Vermutung, dass das bei mir zutreffen wird.
Ich habe einen String und einen State den ich an C# übermittle und zwei "Werte" (Oder was auch immer ich dann brauche wenn ich soweit bin).

Danke für den Tipp mit der StateMachine! Dann kann ich mich dazu etwas einlesen und versuchen 🙂
Funktioniert es denn, wenn ich eine neue Klasse (StateMachine.cs) anlege und das darin schreibe? Der Übersichthalber 🙂

13.01.2023 - 12:42 Uhr

Lösung:

Code im Microcontroller:


Serial.println(winkelWert); //Wichtig: Neue Linie!

Zeile 41 im vorherigen Beitrag: Ändern von ReadExisting() auf ReadLine()

Damit wird gewartet bis die Zeile fertig ist. Sehr schön! 🙂

Frage an die Profis: Kann ich mit der gleichen Methode einen weiteren Wert auslesen bzw. abfragen?
Solange ein Knopf am MC gedrückt ist, soll das Programm die Zeit stoppen. Wenn der Knopf losgelassen wird, soll die gestoppte Zeit angezeigt werden und die gemessenen Grad auch.

Dachte an etwas wie:


while (SerialPort.ReadLine("Spezifische Linie auslesen?"))
            {
                //Zeit stoppen irgendwie? Muss ich noch schauen.
            }

Bzw. ist es denn generell Möglich definiert einen Wert mit SerialPort auszulesen? Aktuell liest er ja alles bis zur nächsten Linie und dann? Muss ich dann die kommende Linie schnell von der anderen Funktion auslesen damit die nicht in meine Anzeige rutscht?

Danke an alle!

13.01.2023 - 08:45 Uhr

Jetzt funktioniert es, wunderbar! Dankeschön!

Eine Frage hätte ich noch dazu: Der Wert den ich anzeige "stockt" bzw. blinkt als ob er die Werte nicht sauber bekommt. In der Konsolenausgabe passiert das gleiche.
Es werden 3 Werte pro Sekunde übertragen. In dem SerialTemplate funktioniert das einwandfrei - allerdings komme ich nicht dahinter warum das da besser funktioniert...

Kann mir jemand einen Denkanstoß geben?


using System;
using System.IO.Ports;
using System.Windows.Forms;
using System.Globalization;
using System.Linq;
namespace Schmid_Prüfprogramm
{
    public partial class Schmid_PP : Form
    {
        string portName;
        int baudRate = 19200;
        SerialPort SerialPort = new SerialPort();
        public Schmid_PP()
        {
            InitializeComponent();
            fillComPortComBoBox();
        }
        private void btn_portVerbinden_Click(object sender, EventArgs e)
        {
            try
            {
                SerialPort.PortName = combox_Portliste.SelectedItem.ToString();
                SerialPort.BaudRate = baudRate;
                SerialPort.Open();
                Console.WriteLine(SerialPort.ReadExisting());
                SerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace, "Fehler", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
            }
        }
        private void fillComPortComBoBox()
        {
            combox_Portliste.Items.AddRange(SerialPort.GetPortNames());
            combox_Portliste.SelectedItem = portName;
        }
        private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = (SerialPort)sender;
            string indata = serialPort.ReadExisting();
            Console.WriteLine(indata);
            updateMessung(indata);
        }
        private delegate void threadSicher(string messung);
        private void updateMessung(string indata)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new threadSicher(updateMessung), new object[] {indata});
            }
            lbl_Anzeige.Text = indata;
        }
    }
}

13.01.2023 - 07:37 Uhr

Ja stimmt, sry. Das habe ich wohl übersehen.
Dankeschön!

12.01.2023 - 16:10 Uhr

Ich glaube ich habe verstanden.
ich habe aendereLabel entfernt und den DataReceivedHandler eingefügt. Jetzt kommt diese Ausnahme:

Fehlermeldung:
System.InvalidOperationException: "Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement lbl_test erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."

Damit das dann funktioniert muss ich mit Invoke jetzt weiter machen. Ich lese mich dazu mal ein. Ein paar Beispiele habe ich gefunden, allerdings nützen die mir nichts wenn ich nicht weiß was Invoke alles bewirkt. Gibt es irgendwo eine bessere Doku dazu als bei learn.microsoft.com?

Dankeschön fürs helfen 🙂

12.01.2023 - 13:37 Uhr

Vielen Dank für den Tipp mit dem Template! Im Prinzip genau das was ich vor habe!

Das mit dem Invoke habe ich mir angeschaut und versucht zu verstehen. Anhand einem Beispiels habe ich das mal versucht einzubinden, bisher ohne Erfolg.
Allerdings hänge ich gerade auch noch an dem einfachen ändern des Label fest...
Könntest du dir das mal ansehen und mir einen Tipp geben warum sich mein lbl_test nicht umschreiben lässt?

In der Konsole bekomme ich den passenden Wert angezeigt, nur das Label zeigt nichts an.


using System;
using System.IO.Ports;
using System.Windows.Forms;
using System.Globalization;
using System.Linq;

namespace Prüfprogramm
{
    public partial class PP : Form
    {
        string portName;
        int baudRate = 19200;
        SerialPort SerialPort = new SerialPort();
       
        public PP()
        {
            InitializeComponent();

            fillComPortComBoBox();

        }

        private void btn_portVerbinden_Click(object sender, EventArgs e)
        {
            try
            {
                SerialPort.PortName = combox_Portliste.SelectedItem.ToString();
                SerialPort.BaudRate = baudRate;

                SerialPort.Open();
                Console.WriteLine(SerialPort.ReadExisting());
                string messwert = SerialPort.ReadExisting();
                aendereLabel(lbl_Anzeige, messwert);
                lbl_test.Text = messwert;
                //SerialPort.Close();
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace, "Fehler", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
            }
            
        }

        private void fillComPortComBoBox()
        {
            combox_Portliste.Items.AddRange(SerialPort.GetPortNames());
            combox_Portliste.SelectedItem = this.portName;
        }

        public void aendereLabel(Label label, string str)
        {
            if (label.InvokeRequired)
            {
                string mw = str;
                label.Invoke(new MethodInvoker(delegate { label.Text = mw.ToString(); }));
            }
        }
    }
}

11.01.2023 - 07:55 Uhr

Hallo Zusammen,

Ich möchte eine kleine Anwendung erstellen, mit dem ich Werte (aktuell Arduino) via USB auslesen und verarbeiten kann.
Der Arduino sendet einen Messwert mit der Funktion Serial.println(value).

Ich habe es bisher halbwegs hinbekommen, den Wert vom SerialPort auszulesen und an ein Label weiterzugeben.
Allerdings übernimmt er den Wert nur wenn ich den button drücke, was soweit in Ordnung wäre.

Ich möchte den IST-Wert vom Arduino in Echtzeit auf dem UI haben und nach der fertigen Messung den Wert speichern.

Nach welcher Funktion muss ich denn suchen um den Wert konstant auszulesen?

Vielen Dank 🙂

Aktueller Codeschnipsel


        public void btn_portOpen_Click(object sender, EventArgs e)
        {
            SerialPort comport = new SerialPort("COM3");
            comport.BaudRate = 19200;
            comport.ReadTimeout = 1000;
            comport.Parity = Parity.None;
            comport.StopBits = StopBits.One;
            try
            {
                //lbl_messwert.Text = "";
                comport.Open();
                int messwert = comport.ReadChar();
                lbl_echtzeit.Text = messwert.ToString();
                //string indata = comport.ReadExisting();
                //Console.Write(indata);
                //lbl_messwert.Text = indata.ToString();
                //comport.Close();
            }
            
            catch (Exception)
            {
                MessageBox.Show("Fehler bei der Portverbindung");
            }

04.02.2022 - 07:57 Uhr

Guten Morgen,

ich habe mir die Invoke-Sache mal angeschaut und versucht anhand eines Beispiels es nachzubauen.
Allerdings kommt nichts dabei raus. Kannst du mir einen Tipp geben warum es im Beispiel klappt, aber bei mir nicht?

Zu Beginn habe ich die delegate deklariert:


    public partial class Form1 : Form
    {
        public delegate void AddDataDelegate(String meinString);
        public AddDataDelegate meinDelegate;


Im Toolstrip wähle ich den Port aus und öffne ihn mittels Click:


        private void cOMPortToolStripMenuItem_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            serialPort1.PortName = sender.ToString();
            serialPort1.Open();
        }

Sobald der Port geöffnet ist, sollte doch das Ereignis anfangen zu arbeiten? Ich habe Testhalber mal eine richtextbox ausgewählt wie in dem Beispiel:


        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string bar = serialPort1.ReadExisting();
            richTextBox1.Invoke(this.meinDelegate, new object[] { bar });
            richTextBox1.Clear();
            
            /* Nicht Thread-sicher!
            string bar = serialPort1.ReadExisting();
            label1.BeginInvoke(bar);
            chart_live.Series.Add("Druck ist");
            chart_live.Series[0].ChartType = SeriesChartType.Line;
            chart_live.Series[0].Points.Add(Convert.ToInt32(bar));
            string bar = serialPort1.ReadExisting();
            label1.Text = bar;
            */
        }

03.02.2022 - 18:13 Uhr

Alles klar, daher auch die vielen Messergebnisse. Danke! 🙂

Nein, ist er wirklich nicht 😉
Das war jetzt mal der erste Schritt für mich, gibt noch einiges zu tun daran.

Genau, mit dem serialPort1_DataReceived Ereignis hatte ich das auch schon versucht. Aber wie du schon geschrieben hast, habe ich Probleme mit dem Threads. Den Link werde ich mir heute Abend mal anschauen - Danke dafür!

03.02.2022 - 17:26 Uhr

Mein chart zeigt nun endlich was an 😁
Noch nicht wirklich schön, aber froh bin ich trotzdem darüber.

Wie läuft das denn ab mit der USB Schnittstelle. Wenn ich länger warte, bis ich den serialPort1 abfrage, habe ich deutlich mehr im chart. Wenn ich das ganze schneller wiederhole, weniger.
Sammeln sich die Daten und warten bis sie jemand abholt oder wie kann man sich das vorstellen? 😁

Ich hänge mal den Code von meinem Arduino noch mit ran.



        private void btn_messungstarten_Click(object sender, EventArgs e)
        {
            chart_druck.Series.Clear();
            chart_druck.Series.Add("Druck");
            chart_druck.Series[0].ChartType = SeriesChartType.Line;
            string readbar = serialPort1.ReadExisting();
            foreach (int bar in readbar) 
            {
                /*
                for (int i = 0; i < 1; i++)
                {
                    chart_druck.Series[0].Points.Add(bar);
                }
                */
                chart_druck.Series[0].Points.Add(bar);
            }
            //serialPort1.Close();
        }


ArduinoCode:


void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(2);
  delay(333);
  Serial.println(3);
  delay(333);
  Serial.println(15);
  delay(333);
  Serial.println(11);
  delay(333);
}

03.02.2022 - 14:17 Uhr

Danke für deine Info!

Mit dem ersten Link komme ich nocht nicht klar - schau ich mir heute Abend in Ruhe an.
Bei dem zweiten kam ich dafür zur besseren Erkenntnis 😁

Aktuell sieht mein Codeschnipsel so aus:


        private void btn_messungstarten_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 3; i++)
            {
                
                string bar = serialPort1.ReadExisting();
                int ibar = Convert.ToInt32(bar);
                chart_druck.Series.Clear();
                chart_druck.Series.Add("Druck");
                chart_druck.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
                chart_druck.Series[0].Points.AddXY(i,ibar);
            }
            serialPort1.Close();
        }

Allerdings werden mir die Punkte noch nicht angezeigt wie gewollt 😁

Ich versuche mich heute Abend nochmal daran.

03.02.2022 - 07:59 Uhr

Guten morgen,

ich möchte mir mithilfe eines Microcontroller ein Messwerkzeug bauen, damit ich Druck und Temperatur auslesen und aufzeichnen kann.
Die Messung selber soll später auf eine Minute begrenzt werden. So viel mal vorab.

Die Seite mit dem Microcontroller funktioniert soweit und ich kann über den USB-Port die Daten einlesen. Aktuell scheitere ich aber beim Versuch, die Messwerte in die Chart zu übergeben.
Könnt ihr mir einen Tipp geben, wie ich die Messwerte in mein Chart bekommen kann? Wenn ich feste Werte nehme, bekomme ich das hin aber halt auch nur dieses Balkenchart und kein Linienchart 😁

Ich möchte keine fertigen Codes haben, nur eine kurze Hilfestellung mit welcher Funktion ich das hinbekommen könnte 🙂

Vorab schonmal DANKE fürs Gedanken machen!

Mein bisheriger Code:
(Konnte man den nicht mal in [Spoiler] setzen?)


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.IO.Ports;
using System.Timers;

namespace HDR_Testprogramm
{
    public partial class Form1 : Form

    {
        public Form1()
        {
            InitializeComponent();

            //Sucht nach verfügbaren Ports und listet diese auf
            string[] ports = SerialPort.GetPortNames();
            foreach(string port in ports)
            {
                ToolStripMenuItem item = new ToolStripMenuItem(port);
                item.Click += cOMPortToolStripMenuItem_Click;
                cOMPortToolStripMenuItem.DropDownItems.Add(item);
            }
            //_________________________________________________________________________
        }


        private void cOMPortToolStripMenuItem_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            serialPort1.PortName = sender.ToString();
            serialPort1.Open();
        }

        private void btn_messungstarten_Click(object sender, EventArgs e)
        {
            int ibar = 0;
            try
            {
                string bar = serialPort1.ReadExisting();
                richTextBox1.AppendText(bar);
                chart_druck.Series.Clear();
                ibar = Convert.ToInt16(bar);
                chart_druck.Series.Add("druck").Points.Add(ibar);
            }
            catch
            {
                MessageBox.Show("Zuerst Port auswählen!");
            }
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //string bar = serialPort1.ReadExisting();
            //label1.Text = bar;
        }

        private void chart_druck_Click(object sender, EventArgs e)
        {
            chart_druck.Series.Clear();
        }

        private void btn_messungstop_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
        }

        private void richtextbox_leeren_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
        }
    }
}

23.07.2020 - 10:23 Uhr

Danke für eure Hilfe!

@Abt
Mir war wohl nicht bewusst, dass der Unterschied zwischen WFA und WPF doch so groß ist...

Bevor ich an hier groß weiter "bastel" (mit programmieren hat das nichts zu tun 😦), lese ich mich zuerst einmal in die MVVM Geschichte ein. Anschließend probiere ich mich an einem DataTable und nicht wieder alle auf einmal.

@Th69
Ich hatte es anfangs versteckt mit Window.hidden, allerdings habe ich (fällt mir eben auf) das versteckte Fenster nicht mehr Sichtbar gemacht sondern neu aufgerufen. Dadurch war ein Fenster immer im Hintergrund und noch Aktiv. Deshalb habe ich meine alte Methode angewand...
Danke.

Ich kümmere mich vorerst um ein paar grundliegende Sachen und versuche es nochmal.
Der Beitrag kann fürs erste als Erledigt angesehen werden.

Danke für euren Beistand! 🙂

22.07.2020 - 17:26 Uhr

Wer ruft denn DatenVonTabelle auf? Und was soll der rekursive Aufruf dadrin

Das sollte aufgerufen werden, sobald Window_Loaded

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                connection.Open();
///dgvCocktails.DataSource = DatenVonTabelle(„Cocktails“); !--Aus dem Tutorial
///DGMitarbeiter.DataSource = DatenVonTabelle("Mitarbeiter");   !--DataSource steht nicht zur Auswahl
             }
            catch (MySqlException exc)
            {
                MessageBox.Show(exc.Message, "Datenbankfehler", MessageBoxButton.OK);
                this.Close();

            }
        }

Und deine Methode ZurückMainWindow erzeugt ein neues MainWindow-Objekt (anstatt zum aufrufenden MainWindow-Objekt zurückzukehren)!

Ist das Falsch? Bzw. nicht ganz Richtig? Beim drücken des Auftragsfensters wird das MainWindow geschlossen und das Auftrags (Mitarbeiter) Fenster geöffnet. Zurück das selbe.

Das mit der Dreischichten-Architektur hatte ich mal angeschnitten, denke das kommt noch so nach und nach. 🤔

Danke für deine Nachricht.

22.07.2020 - 15:11 Uhr

verwendetes Datenbanksystem: <MariaDB10 [SynologyDS218+]>

Hallo zusammen.

Nachdem ich mein letztes Projekt (halbwegs) abgeschlossen habe, mach ich mich an mein nächstes langsam ran.
Ich möchte (langfristig) ein Zentrales Verwaltungssystem für meinen Betrieb basteln. Dafür habe ich mir auch schon ein vorläufiges Design erstellt. Soviel mal dazu.

Ich habe mir das ganze mal angesehen und ein wenig im Internet geschnuppert, aber eine DB lässt sich nicht vermeiden. Da ich unter anderem die NAS von Synology verwende, habe ich MariaDB hierfür gewählt.

Mein aktuelles Problem besteht beim laden der DB in ein DataGrid. Da meine Anleitung etc. dafür nicht geeignet ist, komme ich auch nach einigen Versuchen nicht weiter...

Laut der Anleitung soll ich im Aktionsfenster (rechtsunten) die Aktion "Shown" benutzen. Den gibt es aber nicht. Daher habe ich eine andere genommen, mit der es aber auch nicht ganz will.

Letztendlich kommt (bevor das 2. Fenster aufgeht) eine Fehlermeldung: Unable to connect to any of the specified MySQL hosts.
Mit einem SQL Tester kann ich aber die Verbindung aufbauen?

Eventuell hat mir ja jemand einen Hinweis woran es liegen könnte.

Vielen Dank für eure Mithilfe!!!!

EDIT: Ich habe die Fehlermeldung mittlerweile wegbekommen. Window_Loaded war das richtige. Allerdings habe ich noch keinen Inhalt aus der DB?


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using MySql.Data;
using MySql.Data.MySqlClient;
using MySql.Web;
using System.Data;
using System.Data.Common;

namespace SCM
{



    /// <summary>
    /// Interaktionslogik für Auftragsverwaltung.xaml
    /// </summary>
    public partial class Auftragsverwaltung : Window
    {
            MySqlConnection connection = new MySqlConnection();
            private string db_server = "192.168.0.77";
            private string db_user = "root";
            private string db_password = "PRIVATE";
            private string db_name = "SCMDATA";
            private string db_port = "3307";


        public Auftragsverwaltung()
        {
            InitializeComponent();
            connection.ConnectionString = "Server=" +db_server + "; Database=" +db_name + "; Uid=" +db_user + "; Pwd=" +db_password + "; Port=" +db_port + ";";
        }

        private void ZurückMainWindow(object sender, RoutedEventArgs e)
        {
            MainWindow mainWindow = new MainWindow();
            this.Close();
            mainWindow.Show();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                connection.Open();
            }
            catch (MySqlException exc)
            {
                MessageBox.Show(exc.Message, "Datenbankfehler", MessageBoxButton.OK);
                this.Close();

            }



        }

        public DataTable DatenVonTabelle(string Tabelle, string Filter = "")
        {
            DataTable dt = new DataTable();
            try
            {
                if (connection.State != ConnectionState.Open)
                    connection.Open();
                DGAuftrag.DataContext = DatenVonTabelle("Mitarbeiter");
                String abfrage = "SELECT* FROM " +Tabelle + (Filter == "" ? String.Empty : " WHERE " +Filter);
                MySqlDataAdapter msda = new MySqlDataAdapter(abfrage, connection);
                msda.Fill(dt);
                connection.Close();
            }
            catch (MySqlException e)
            {
                MessageBox.Show(e.Message, "Datenbankfehler", MessageBoxButton.OK);
                if (connection.State == ConnectionState.Open) connection.Close();
            }
            return dt;
        }




    }
}


10.10.2019 - 16:38 Uhr

Danke!

Hab es geschafft. 🙂
Das Programm speichert mir die Datei lokal ab und lädt diese anschließend auf meinen FTP.

Danke 8) 👍

09.10.2019 - 18:02 Uhr

Hallo zusammen,

Ich arbeite immer noch an meinem kleinen Programm mit dem ich Farben erfassen kann und an einem anderen Ort wieder abrufen kann.
Ich kann Dateien laden und speichern - lokal bei mir. Wenn ich den Pfad auf meinen FTP ändere, lädt er mir meine Datei in das Programm, aber speichern kann ich das nicht - was ich aber gern machen würde 😃
Mit dem SaveFileDialog geht das ganze nicht, soviel weiß ich.

Jetzt meine Frage: Muss ich meine Datei lokal abspeichern und dann hochladen oder geht das "einfacher".

Danke schon mal fürs Gedanken machen 😃

02.10.2019 - 11:41 Uhr

Ich danke dir für deine Bemühungen und deinen Beistand zu meinen (vielen) Fragen! 🙂

Ich werde mir wie gesagt diese Woche noch den Kurs reinhämmern um die Grundlagen einfach mal zu verstehen. Da hab ich doch noch viele Defizite gefunden. Ich denke die sollten schon sitzen bevor man sich in ein zu großes "Anfängerprojekt" reinstürzt.

Sobald ich damit durch bin, werde ich mir mal deinen Code vorknüpfen. Eventuell fällt mir das dann etwas leichter. 😁

Als Hinweis für später: Warten auf Schließen einer anderen Form [und warum man Dialoge nicht modal machen sollte] und Nenne deinen Fall, wo du denkst, ohne modalen Dialog geht es nicht, und ich nenne eine Alternative

Über die MSGBox habe ich schon mehr gelesen, dass diese nicht unbedingt eine gute Wahl ist. Allerdings nehm ich diese gern für "kleine" Ausgaben. Zumindest für Übungszwecke...

Ich würde das hier dann mal vorerst als -gelöst- betrachten.

Abschließende Frage noch an dich: Du gibst nicht zufällig "Onlinekurse" oder ähnliches? 😁 👍

02.10.2019 - 08:26 Uhr

Danke für den Hinweis mit dem Dictionary!
Vom Prinzip her gefällt mir das schon ganz gut 😄

Hab mal eine einfache Übung gemacht mit der ich RAL, Lagerort und Gewicht hinzufügen kann und mir diese im msgbox ausgibt.

Werde mich die Tage mal mit deinem Programm auseinander setzen. Da das schon ziemlich komplex ist, werd ich wohl etwas länger benötigen. Vorallem so viele Klassen und keine Ahnung wieviel da noch drin ist 😮

Bei mir sind "Programme" immer nur auf einer Seite... Zumindest noch.

Du hast viele Funktionen drin von denen ich noch nie gehört habe. Denke ich brauch bis dahin noch etwas.
Habe gestern noch mit einem C# "Kurs" angefangen, da mir doch einiges von Grund auf noch fehlt.
Denke es ist besser wenn ich diesen vorab mache um zumindest gewisse Grundkenntnisse und die Strukturen zu erlernen.

public void btn_eingeben_Click(object sender, EventArgs e)
        {
            string RALbox = txt_in_1.Text;
            string Lagerbox = txt_in_2.Text;
            string Kilobox = txt_in_3.Text;
            Dictionary<string, string> farben = new Dictionary<string, string>();

            farben.Add("RAL", RALbox);
            farben.Add("Lagerort", Lagerbox);
            farben.Add("kg", Kilobox);

            MessageBox.Show("RAL " + RALbox + "\n" + "Lagerort " + Lagerbox + "\n" + "kg" + Kilobox);


        }
01.10.2019 - 16:49 Uhr

Vielen Dank für deine Bemühungen!!!

Du willst eine Übersicht haben, die angibt wieviel von der jeweiligen Farbe an welchem Lagerort vorhanden ist. Korrekt?

Genau, ich möchte wissen welche Farbe, an welchem Lagerort, in welcher Masse vorhanden ist.

Überleg dir generell was du abbilden willst. Wie das geschehen soll lass vorerst außer Acht.

Habe ein Bild mit angefügt wie ich das machen möchte.

Ich hab das Gefühl dass das auch stimmt, daher hab ich ein kleines Projekt gebastelt, andem du dich orientieren kannst. Siehe Anhang.
VS 2017 od. neuer mit installierten .NET 4.8 ist nötig (kann sicher auch auf .NET 4.5 laufen).

Vielen Dank! Ich hoffe du bist nicht so lange dran gesessen extra wegen mir 8o

Ich habe mir das Projekt mal angesehen, allerdings brauche ich immer ein wenig bis ich andere Codes gelesen habe und mir durchblick verschafft hab. 😁

Mit dem Dictionary muss ich mich noch einlesen, da finde ich sicherlich ein paar How2 im Netz..

Danke für deine Hilfe! 🙂

EDIT: Bild vergessen anzufügen

30.09.2019 - 17:37 Uhr

verwendetes Datenbanksystem: XML

Ich arbeite an einem Programm mit dem ich Farbpulverbestände und deren Lagerort erfassen kann.
Beim eingeben gibt es drei Textboxen die das in eine XML schreiben.
Nach langem probieren und lesen kann ich die Struktur nun endlich wie gewünscht abspeichern.
Bei jedem Speichervorgang überschreibt er mir die ganze Datei, ähnlich wie bei txt-Dateien, allerdings finde ich keine AppendAll ähnlichen Befehle.

Was ich vor habe:
Beim eingeben der Werte (RAL, Lagerort, Gewicht) soll geprüft werden, ob RAL schon vorhanden ist, wenn ja: das Gewicht zum bestehenden dazu addieren. Sollte der Lagerort gleich sein, aber die RAL unterschiedlich müsste eine einfache Msgbox auftauchen.
Wenn kein RAL und kein Lagerort vorhanden, müsste ein neuer Eintrag hinzugefügt werden.
Das ganze soll in einer Listbox (gern auch was anderes wenn inkompatibel) angezeigt werden.

Meine Frage: Ist das ganze einfacher mit einer Datenbank? Ich habe mich noch nie groß damit beschäftigt daher kenne ich mich damit nicht gut aus.

Ich möchte keinen Code ergaunern, wenn mir jemand ein paar Tipps geben kann wie ich das angehen soll probiere ich gern ein wenig aus. Ja - Ich bin ein Neuling in Sachen C# und programmieren im Allgemeinen... Daher sieht mein Code komisch aus und ist nicht perfekt 😄

Anbei mein Code bis jetzt:

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Xml.Linq;


namespace PulverExplorer
{
    public partial class Bearbeiten : Form
    {
        public Bearbeiten()
        {
        
        InitializeComponent();
        }

        private void speichernUndSchließenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                //------------------------
                // Speichert 
                /*Datenklasse datenklasse = new Datenklasse();

                datenklasse.RAL = txt_in_RAL.Text;
                datenklasse.LAGERORT = txt_in_Lagerort.Text;
                datenklasse.GEWICHT = txt_in_Gewicht.Text;

                Datenspeichern.SaveDaten(datenklasse, "C:\\Desktop\\Datenblock.xml");
                this.Close();
                */
                //-----------------------
                //Versuch zum speichern im Baum
                XElement Farben =
                    new XElement("Farbübersicht",
                        new XElement("RAL", txt_in_RAL.Text),
                        new XElement("Lagerort", txt_in_Lagerort.Text),
                        new XElement("Gewicht", txt_in_Gewicht.Text));

                        
                Datenspeichern.SaveDaten(Farben, "C:\\Desktop\\Datenblock.xml");

            }
            catch
            {
                MessageBox.Show("Hoops");
            }
          
        }  
        

        private void abbrechenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_Eintragen_Click(object sender, EventArgs e)
        {
            
            /*
            string Pfad = @"C:\test.txt";
            string RAL = txt_in_RAL.Text;
            string Lagerort = txt_in_Lagerort.Text;
            string Gewicht = txt_in_Gewicht.Text;

            File.AppendAllText(Pfad,"\n" + RAL + "\t" + "\t" + Lagerort + "\t" + "\t" + Gewicht);
            */
        }
    }
}

Datenspeichern.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml.Serialization;

namespace PulverExplorer
{
    public class Datenspeichern
    {
        public static void SaveDaten(object obj, string filename)
        {
            XmlSerializer sr = new XmlSerializer(obj.GetType());
            TextWriter writer = new StreamWriter(filename);
            sr.Serialize(writer, obj);
            writer.Close();
        }
    
    }
}

Das kommt dabei raus:

<?xml version="1.0" encoding="utf-8"?>
<Farbübersicht>
  <RAL>5018</RAL>
  <Lagerort>1.658</Lagerort>
  <Gewicht>14.5</Gewicht>
</Farbübersicht>
26.09.2019 - 16:09 Uhr

Ok, da muss ich mich wohl länger mal einlesen...
Hab grad mal etwas nachgeschlagen mit dem Linq2XML, da wird´s mir gleich schwindlig...

Gut ich glaub ich fange mal mit einfacheren Suchfunktionen an, bzw. zuerst muss ich mir das Speichern beibringen sonst gibt es nicht´s zu lesen 😛

26.09.2019 - 15:44 Uhr

Der Grobe Ansatz passt ja aber? 😃

Wenn ich das in der Form mache:<Item Type="RAL5018">
Dann wäre dem nur <Farbtabelle> übergeordnet und die Werte <Lagerort> und <Gewicht> untergeordnet zu <Item Type="RAL5018">

Versteh ich das so richtig.

Also sollte ich später eine Suchfunktion mit einbinden könnte ich z.b. nach RAL5018 suchen und bekäme die Werte darunter mitgeliefert?

@BerndFfm
Danke für deinen Hinweis, hatte mir JSON auch schon ins Auge gefasst, möchte aber vorerst mal bei XML bleiben. Finde da iwie leichter den Einstieg. Danke 😃

26.09.2019 - 14:09 Uhr

Wollte ich ebenfalls vorschlagen:

Visual Studio

Alternativ evtl mit dem Atom Editor noch versuchen..

26.09.2019 - 14:07 Uhr

Danke für eure Anteilnahme! 🙂

@gfoidl
Hatte mir das ganze so gedacht:
in der Hauptform ist eine Listbox (oder ähnlich) in der mir die Daten angezeigt werden.
Mittels der BearbeitenForm kann ich die Liste bearbeiten, also hinzufügen und entfernen bzw. nur einen Parameter bearbeiten. (Mittelfristig dachte ich an eine Art Passwortabfrage, da aber auf die Liste nur ab und zu zugegriffen wird von max 2-3 Personen seh ich das nicht so eng. Zudem sind es keine Sensiblen Daten 🙂 )

@T-Virus
Mit der DB hatte ich mich gestern Abend mal bissl auseinander gesetzt. (Microsoft SQL Server)
Da das aber ein riesiges Thema ist schieb ich das noch ein Wenig. Zudem ich die DB auf meinem rootserver haben möchte und nicht nur Lokal. Problem ist, ich muss die Daten an Ort A überwiegend eingeben und an Ort B eigentlich nur abrufen bzw. einsehen können.
Das die Variante mit XML nicht die perfekte ist denk ich mir auch. Allerdings für mich als totalen einsteiger ist das schon ein großes Projekt 😁 👍

Hab mich mal mit dem XML ein wenig beschäftigt. Ich glaube von der Struktur her komme ich klar. Falls es jemand interessiert hier ist mal ein Beispiel:


<?xml version="1.0" encoding="utf-8" ?>
<Farbtabelle>
  
  <RAL5018>
    <Lagerort>106</Lagerort>
    <Gewicht>14.5</Gewicht>
  </RAL5018>

  <RAL7035>
    <Lagerort>108</Lagerort>
    <Gewicht>8</Gewicht>
  </RAL7035>

  <RAL7016>
    <Lagerort>110</Lagerort>
    <Gewicht>18</Gewicht>
  </RAL7016>

</Farbtabelle>

26.09.2019 - 11:25 Uhr

Befasse mich gerade auch ein bissl mit XML.
Vielleicht hilft dir das ja:
Deserialisieren XML

26.09.2019 - 11:08 Uhr

@Stefan.Haegele
Normal schreibe ich nicht auf C: - War halt nur zur Veranschaulichung 😃

@gfoidl
Jetzt wo du es schreibst, ich glaube ich hatte den Port vergessen einzutragen...
Hab es zuvor mit HeidiSQL versucht (Port 3306), da wollte es ebenfalls nicht.
Ich kann doch die Listbox direkt mit einer Datenbank verbinden? Im Designer die Listbox auswählen und rechts oben an der Ecke "An Daten gebundene Elemente verwenden".
Oder gibt es da einen besseren Weg?

Ich sag mal so: Die Datenmenge hält sich in Grenzen. Wenn ich 60 Positionen mit jeweils 3 Angaben habe ist das schon das Maximum.

26.09.2019 - 07:23 Uhr

Danke für die Antwort.
Ja, das ich mit der Textdatei nicht weit komme wusste ich. Jedoch für meinen Einstieg fand ich das am einfachsten. 😃
Ich hatte auch schon eine SQL Datenbank ins Auge gefasst, allerdings komm ich mit der Verbindung zwischen dem Programm und meinem Server nicht klar.
Werd das wohl über die XML machen und Dateiaustausch mittels FTP.

Dankeschön! 😃

25.09.2019 - 15:28 Uhr

Eine Frage hätte ich noch...

Ich habe in meiner Liste bereits eine Zeile mit beispielsweise:
RAL 5018 Lagerort 100

Wenn ich jetzt dieselbe Farbe dazufügen möchte legt er mir so eine weitere Farbe an. Ist es möglich nur auf das Gewicht dazu zu addieren?

25.09.2019 - 13:24 Uhr

Super, mit ein bissl basteln hab ichs hinbekommen.

Vielen Dank!!!

Hier der Code:


private void btn_Eintragen_Click(object sender, EventArgs e)
        {
            string Pfad = @"C:\test.txt";
            string RAL = txt_in_RAL.Text;
            string Lagerort = txt_in_Lagerort.Text;
            string Gewicht = txt_in_Gewicht.Text;

            File.AppendAllText(Pfad,"\n" + RAL + "\t" + "\t" + Lagerort + "\t" + "\t" + Gewicht);
         }

25.09.2019 - 12:13 Uhr

Hallo zusammen,

ich bastel gerade an einem einfachen Projekt mit dem ich einfach verschiedene Farben, Lagerort und Gewicht erfassen und danach suchen kann.
Das ganze wird (vorläufig) in einer txt Datei gespeichert (irgendwann auf meinem Server) und in einer Listbox angezeigt.

Wenn ich etwas neu hinzufügen möchte (zu der bestehenden txt Datei) überschreibt er mir alles und fügt nur den neuen Wert ein.
Ich würde das ganze jeweils in einer Zeile schreiben. Wobei jede Zeile eine neue Farbe sein soll.

Könnte mir da jemand einen denkanstoß geben? Bin den ganzen Vormittag am suchen aber finde nicht´s spezielles auf mein Problem...


private void btn_Eintragen_Click(object sender, EventArgs e)
        {
            string RAL = txt_in_RAL.Text;
            string Lagerort = txt_in_Lagerort.Text;
            string Gewicht = txt_in_Gewicht.Text;
            File.WriteAllText(@"C:\test.txt", RAL + "\t" + "\t" + Lagerort + "\t" + "\t" + Gewicht);
        }

Danke 😃

26.02.2018 - 07:18 Uhr
((Person)dataGridViewMitarbeiter.SelectedRows).Kommt();  

Danke dafür, allerdings kommt die Fehlermeldung: > Fehlermeldung:

Der Typ kann nicht konvertiert werden.

Nachtrag: Ich übersah das der Code genau der selbe wie meiner war, und du nur auf die Artikel weisen wolltest. Ich werde mir diese mal durchlesen heute. Ist anscheinend doch ein größeres Fass 😄

@MrSparkle: Mit dem schreiben komm ich klar soweit, ich habe die DB-Table mit dem PGM verbunden und per Drag-Drop einfach auf die Form gezogen - Fertig. Ich möchte nur gerne eine bzw. zwei Spalten aus unterschiedlichen Tabellen auswählen und mit einem Button in eine andere DB einen Eintrag damit erstellen.

24.02.2018 - 10:23 Uhr

Danke für die schnelle Antwort.
Wie erkläre ich das am besten... 🤔

Der Code ist von dem Kommt-Button, bei meiner anderen Übung habe ich aus einer Listbox einen Mitarbeiter ausgewählt und mit dem Button quasi die Zeit erfasst.
Jetzt möchte ich aus der dataGridView-box auch den Mitarbeiter, bzw die Spalte auswählen und diese Zeit erfassen die dann in einer DB angelegt wird.

Ich hoffe ich konnte es etwas verständlicher ausdrücken.
Hab mal noch nen Screen von der Oberfläche mit angehängt eventuell kann man dann verstehen was ich vorhabe.

Soll ich mehr von dem Code mit angeben? Ich wollte nicht dass es sonst so überladen ist.