From 3314e8e6467fa02f4949a641cfe7e2e0a0f5dfcc Mon Sep 17 00:00:00 2001 From: Kilian Wirl Date: Wed, 10 Dec 2025 17:28:20 +0100 Subject: [PATCH] =?UTF-8?q?WSVerfolgung=20Laden=20der=20Controls=20verbess?= =?UTF-8?q?ert,=20Ordnung=20und=20Comments=20in=20WSVerfolgung=20angepasst?= =?UTF-8?q?,=20FehlmengeCount=20-=20SingleSPLT=20bei=20Frottee=20anzeigen,?= =?UTF-8?q?=20Expedit=20=C3=84nderungen=20an=20dgArtikel=20und=20OLV,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AA-Forms/FormExpedit.Designer.cs | 40 ++--- AA-Forms/FormExpedit.cs | 159 ++++++++++++------ AA-Forms/FormFehlmengeCount.cs | 5 +- AA-Forms/FormListe.cs | 1 - AA-Forms/FormWSVerfolgung.Designer.cs | 32 ++-- AA-Forms/FormWSVerfolgung.cs | 143 +++++++++++----- AA-Klassen/Fehlermeldungen.cs | 2 +- App.config | 2 +- Properties/Resources.Designer.cs | 10 ++ Properties/Resources.resx | 3 + ...g_signal_alert_exclamation_icon_124159.png | Bin 0 -> 18778 bytes 11 files changed, 260 insertions(+), 137 deletions(-) create mode 100644 Resources/weather_warning_signal_alert_exclamation_icon_124159.png diff --git a/AA-Forms/FormExpedit.Designer.cs b/AA-Forms/FormExpedit.Designer.cs index d9d699b..97319f4 100644 --- a/AA-Forms/FormExpedit.Designer.cs +++ b/AA-Forms/FormExpedit.Designer.cs @@ -29,8 +29,8 @@ private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormExpedit)); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); this.label10 = new System.Windows.Forms.Label(); this.buttonDrucken = new System.Windows.Forms.Button(); this.buttonAbbrechen = new System.Windows.Forms.Button(); @@ -491,14 +491,14 @@ // this.dGArtikel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Right))); - dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; - dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; - dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; - this.dGArtikel.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dGArtikel.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle3; this.dGArtikel.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.dGArtikel.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.KundeArtikelID, @@ -511,14 +511,14 @@ this.StandBearbeitet, this.FehlmengeBearbeitet, this.KorrekturBearbeitet}); - dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.dGArtikel.DefaultCellStyle = dataGridViewCellStyle2; + dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dGArtikel.DefaultCellStyle = dataGridViewCellStyle4; this.dGArtikel.Location = new System.Drawing.Point(638, 42); this.dGArtikel.Name = "dGArtikel"; this.dGArtikel.RowHeadersWidth = 62; @@ -683,12 +683,12 @@ // // buttonEinstellung // - this.buttonEinstellung.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonEinstellung.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonEinstellung.FlatAppearance.BorderColor = System.Drawing.Color.White; this.buttonEinstellung.FlatAppearance.BorderSize = 3; this.buttonEinstellung.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.buttonEinstellung.Image = global::Deckungsbeitrag.Properties.Resources.Monaco_Settings_16x; - this.buttonEinstellung.Location = new System.Drawing.Point(1431, 9); + this.buttonEinstellung.Location = new System.Drawing.Point(1022, 727); this.buttonEinstellung.Name = "buttonEinstellung"; this.buttonEinstellung.Size = new System.Drawing.Size(41, 41); this.buttonEinstellung.TabIndex = 45; diff --git a/AA-Forms/FormExpedit.cs b/AA-Forms/FormExpedit.cs index de2ba01..a75f54b 100644 --- a/AA-Forms/FormExpedit.cs +++ b/AA-Forms/FormExpedit.cs @@ -12,6 +12,7 @@ namespace Deckungsbeitrag { public partial class FormExpedit : Form { + private ToolTip cellTooltip = new ToolTip(); public Fehlermeldungen fehlermeldung = new Fehlermeldungen(); public Image etikett = null; public Auftrag auftrag; @@ -66,8 +67,10 @@ namespace Deckungsbeitrag { Cursor.Current = Cursors.WaitCursor; this.SuspendLayout(); + this.Visible = false; - imagelist.Images.Add(Resources.WarningRule_16x); + imagelist.Images.Add(Resources.Exclamation_Red); + imagelist.ImageSize = new Size(24, 24); // Controls aktivieren und deaktivieren nach BenutzerRolle switch (this.benutzer.Rolle) @@ -125,6 +128,7 @@ namespace Deckungsbeitrag this.ResumeLayout(); + this.Visible = true; Cursor.Current = Cursors.Default; WindowState = FormWindowState.Maximized; } @@ -165,7 +169,7 @@ namespace Deckungsbeitrag if(auftrag != null) { Auftrag _auftrag = Auftrag.GetAuftrag(auftrag.AuftragID); - Load_Gridview(_auftrag); + if(dGArtikel.Visible) Load_Gridview(_auftrag); } Cursor.Current = Cursors.Default; @@ -257,9 +261,16 @@ namespace Deckungsbeitrag // Alle Zeilenhöhen an Zellinhalt anpassen this.dGArtikel.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; + //TODO: Breite der GridView festlegen. this.dGArtikel = Funktionen.DGV_Size_Anpassen(this.dGArtikel); + this.dGArtikel.Width = this.Width - dGArtikel.Left; + + // Rechter Rand von letzter Spalte berechnen. + int x = 0; + foreach (ColumnHeader col in objectListViewAuftrag.Columns) x += col.Width;// x ist jetzt die Position direkt rechts von der letzten Spalte (relativ zu client origin) + - this.dGArtikel.Location = new Point(this.tabControlAuftragList.Right - dGArtikel.Width, this.dGArtikel.Location.Y); + this.dGArtikel.Location = new Point(this.objectListViewAuftrag.Left + x, this.dGArtikel.Location.Y); if (this.dGArtikel.Rows.Count > 0) this.dGArtikel.Visible = true; else this.dGArtikel.Visible = false; } @@ -379,9 +390,10 @@ namespace Deckungsbeitrag private void objectListViewAuftrag_CellClick(object sender, CellClickEventArgs e) { itemlocation = new Point(e.Location.X, e.Location.Y); - if(e.Model == null) return; ObjectListView olv = (ObjectListView)sender; Auftrag _auftrag = (Auftrag)e.Model; + + if (e.Model == null) { dGArtikel.Visible = false; return; } if (_auftrag.Status != AuftragStatus.Fertig) { this.auftrag = _auftrag; @@ -396,6 +408,7 @@ namespace Deckungsbeitrag } foreach (Control ctr in this.groupBoxEtikett.Controls) if (ctr.Enabled == false) ctr.Enabled = true; this.buttonKundeNr.Enabled = false; + olv.Focus(); } @@ -521,66 +534,99 @@ namespace Deckungsbeitrag Cursor.Current = Cursors.Default; } - private void OLV_Load(ObjectListView olv, List auftraglist) +private void OLV_Load(ObjectListView olv, List auftraglist) +{ + // Cursor auf Warte-Status setzen, um Benutzerfeedback zu geben + Cursor.Current = Cursors.WaitCursor; + + // Layout- und Update-Änderungen pausieren, um Flackern zu verhindern + olv.SuspendLayout(); // Stoppt Layout-Berechnungen (Anchor/Dock) + olv.BeginUpdate(); // Stoppt Datenaktualisierungen/Redraws + + // Automatisch alle Properties von Auftrag als Spalten generieren + Generator.GenerateColumns(olv, typeof(Auftrag), true); + + // ========== SPALTE 11: BUTTON-KOLUMNE ========== + // Spalte 11 (Index 11) als Button-Spalte konfigurieren + OLVColumn buttonColumn = (OLVColumn)olv.Columns[11]; + buttonColumn.IsButton = true; // Als Button rendern + buttonColumn.ButtonSizing = OLVColumn.ButtonSizingMode.CellBounds; // Button füllt gesamte Zelle + + // ========== IMAGE-LIST ZUWEISEN ========== + // SmallImageList für Icons in Detail-View (16x16 Pixel standard) + olv.SmallImageList = imagelist; // Voraussetzung: imagelist mit Icon Index 0 gefüllt + + // ========== SPALTE 10: ICON-KOLUMNE ========== + // Spalte 10 als Icon-Spalte: zeigt Icon wenn AufgabeID vorhanden + OLVColumn iconColumn = (OLVColumn)olv.Columns[10]; + iconColumn.ImageGetter = rowObject => { - Cursor.Current = Cursors.WaitCursor; - olv.SuspendLayout(); - olv.BeginUpdate(); - - Generator.GenerateColumns(olv, typeof(Auftrag), true); - - // Spalte zum Sortieren festlegen. - OLVColumn sortcolumn = (OLVColumn)olv.Columns[5]; - olv.Sort(sortcolumn); - - // Spalte mit Button anzeigen. - OLVColumn buttonColumn = new OLVColumn(); - buttonColumn = (OLVColumn)olv.Columns[11]; - buttonColumn.IsButton = true; - buttonColumn.ButtonSizing = OLVColumn.ButtonSizingMode.CellBounds; - - // Liste mit Images der ObjectListView zuweisen. - olv.SmallImageList = imagelist; - - // Spalte mit Image anzeigen. Wenn AufgabeID != null dann Image. KEINE UNTERSCHEIDUNG WELCHE AUFGABE. - OLVColumn iconColumn = (OLVColumn)olv.Columns[10]; - iconColumn.ImageGetter = rowObject => - { var auftrag = rowObject as Auftrag; + if (auftrag.AufgabeID == null) return null; // null = kein Icon anzeigen + else return 0; // Index 0 aus SmallImageList + }; - if (auftrag.AufgabeID == null) return null; // kein Icon - else return 0; // Icon an Position 0 - }; - - // Erst nach den Columns die Objecte einfügen. - olv.SetObjects(auftraglist); - - - olv.CheckedAspectName = "IsChecked"; - Funktionen.Columns_Resize(olv); - olv.Columns[0].Width = 0; - olv.Columns[7].Width = 0; - olv.Columns[8].Width = 0; - olv.Columns[9].Width = 0; - - if (olv.Name.Contains("Auftrag")) - { - this.labelauftragtag.Text = olv.Items.Count.ToString(); - int summe = 0; - foreach(var obj in olv.Objects) + // ========== TOOLTIP FÜR ICON-SPALTE ========== + // Automatischer Cell-Tooltip bei Mouse-Hover über Spalte 10 + olv.CellToolTipShowing += (s, e) => + { + // Nur für Icon-Spalte (Index 10) und gültiges Model + if (e.ColumnIndex == 10 && e.Model is Auftrag auftrag) { - Auftrag auf = (Auftrag)obj; - if(auf.Erstellt.Value.Date == DateTime.Now.Date) summe += auf.ContainerClean; + // Lade Bezeichnung der Aufgabe als Tooltip-Text + e.Text = Aufgabe.GetAufgabe(null, auftrag.AufgabeID).Bezeichnung; + } + }; + + // ========== DATEN LADEN ========== + // WICHTIG: SetObjects NACH Column-Konfiguration aufrufen! + olv.SetObjects(auftraglist); // Bindet die Auftragsliste an die View + + // ========== SORTIERUNG ========== + // Spalte 5 als primäre Sortier-Spalte festlegen (nach Datenbindung!) + OLVColumn sortcolumn = (OLVColumn)olv.Columns[5]; + olv.Sort(sortcolumn); // Sortiert aufsteigend nach Spalte 5 + + // ========== CHECKBOX-FUNKTIONALITÄT ========== + // Aktiviert Checkboxen basierend auf "IsChecked" Property des Auftrag-Modells + olv.CheckedAspectName = "IsChecked"; + + // ========== SPALTEN ANPASSEN ========== + Funktionen.Columns_Resize(olv); // Externe Funktion für responsive Spaltenbreiten + + // Unsichtbare Spalten (Width = 0 = versteckt) + olv.Columns[0].Width = 0; // Spalte 0 verstecken + olv.Columns[7].Width = 0; // Spalte 7 verstecken + olv.Columns[8].Width = 0; // Spalte 8 verstecken + olv.Columns[9].Width = 0; // Spalte 9 verstecken + + // ========== STATISTIKEN (nur bei Auftrags-OLV) ========== + if (olv.Name.Contains("Auftrag")) + { + // Anzahl sichtbarer Aufträge anzeigen + this.labelauftragtag.Text = olv.Items.Count.ToString(); + + // ContainerClean-Summe für heute berechnen + int summe = 0; + foreach (var obj in olv.Objects) // Durch alle Modelle iterieren + { + Auftrag auf = (Auftrag)obj; + // Nur Aufträge von heute zählen + if (auf.Erstellt.Value.Date == DateTime.Now.Date) + summe += auf.ContainerClean; } this.labelcontainertag.Text = summe.ToString(); - } - - - olv.EndUpdate(); - olv.ResumeLayout(); - Cursor.Current = Cursors.Default; } + // ========== AUFRÄUMEN & AKTIVIEREN ========== + olv.EndUpdate(); // Update-Pause beenden, Daten neu zeichnen + olv.ResumeLayout(); // Layout-Pause beenden, Positionen neu berechnen + olv.Focus(); // OLV fokussieren (Tastaturbedienung aktivieren) + + // Cursor zurücksetzen + Cursor.Current = Cursors.Default; +} + /// /// Liefertag wird ermittelt und in Day of Week umgerechnet. RadioButtons werden Checked oder Unchecked und Click wird registriert. /// @@ -707,5 +753,6 @@ namespace Deckungsbeitrag einstellung.ShowDialog(); } + } } diff --git a/AA-Forms/FormFehlmengeCount.cs b/AA-Forms/FormFehlmengeCount.cs index 7cc249c..e6aad7a 100644 --- a/AA-Forms/FormFehlmengeCount.cs +++ b/AA-Forms/FormFehlmengeCount.cs @@ -128,7 +128,7 @@ namespace Deckungsbeitrag case var nr when nr.ToString().StartsWith("6312") & nr.ToString().EndsWith("1"): //DUSCHTUCH BLAU this.buttonArt7.Tag = artikel; break; - case var nr when nr.ToString().StartsWith("6354"): //GESICHTSTUCH + case var nr when nr.ToString().StartsWith("61115") & (nr.ToString().EndsWith("00") || nr.ToString().EndsWith("30")): //SPANNLEINTUCH SINGLE this.buttonArt8.Tag = artikel; break; default: @@ -287,9 +287,6 @@ namespace Deckungsbeitrag } } - // Focus auf TextBox damit Kundennummer eingegeben oder gescannt werden kann - //this.textBoxScann.Focus(); - //Kunde wird durch Scan oder Handeingabe Ausgewählt. this.kunde = Funktionen.KundenAuswahl(); ControlLaden(); diff --git a/AA-Forms/FormListe.cs b/AA-Forms/FormListe.cs index 44421b7..7bc2096 100644 --- a/AA-Forms/FormListe.cs +++ b/AA-Forms/FormListe.cs @@ -68,7 +68,6 @@ namespace Deckungsbeitrag timer.Interval = 1000; // 1 Sekunden timer.Tick += Timer_Tick; - this.buttonOK.Visible = this.buttonOK.Enabled = false; listViewKunde_Load(); diff --git a/AA-Forms/FormWSVerfolgung.Designer.cs b/AA-Forms/FormWSVerfolgung.Designer.cs index d6abc29..61672e5 100644 --- a/AA-Forms/FormWSVerfolgung.Designer.cs +++ b/AA-Forms/FormWSVerfolgung.Designer.cs @@ -29,8 +29,8 @@ private void InitializeComponent() { this.statusStripWSVerfolgung = new System.Windows.Forms.StatusStrip(); - this.tableLayoutPanelWSVerfolgung = new System.Windows.Forms.TableLayoutPanel(); this.toolStripDropDownButtonInfo = new System.Windows.Forms.ToolStripDropDownButton(); + this.tableLayoutPanelWSVerfolgung = new System.Windows.Forms.TableLayoutPanel(); this.statusStripWSVerfolgung.SuspendLayout(); this.SuspendLayout(); // @@ -46,20 +46,6 @@ this.statusStripWSVerfolgung.TabIndex = 0; this.statusStripWSVerfolgung.Text = "statusStrip1"; // - // tableLayoutPanelWSVerfolgung - // - this.tableLayoutPanelWSVerfolgung.BackColor = System.Drawing.Color.Transparent; - this.tableLayoutPanelWSVerfolgung.ColumnCount = 1; - this.tableLayoutPanelWSVerfolgung.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanelWSVerfolgung.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanelWSVerfolgung.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanelWSVerfolgung.Name = "tableLayoutPanelWSVerfolgung"; - this.tableLayoutPanelWSVerfolgung.RowCount = 2; - this.tableLayoutPanelWSVerfolgung.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanelWSVerfolgung.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanelWSVerfolgung.Size = new System.Drawing.Size(800, 422); - this.tableLayoutPanelWSVerfolgung.TabIndex = 1; - // // toolStripDropDownButtonInfo // this.toolStripDropDownButtonInfo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))))); @@ -74,6 +60,20 @@ this.toolStripDropDownButtonInfo.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.toolStripDropDownButtonInfo.ToolTipText = "Wähle hier eine Info für die Ausschlager"; // + // tableLayoutPanelWSVerfolgung + // + this.tableLayoutPanelWSVerfolgung.BackColor = System.Drawing.Color.Transparent; + this.tableLayoutPanelWSVerfolgung.ColumnCount = 1; + this.tableLayoutPanelWSVerfolgung.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanelWSVerfolgung.Dock = System.Windows.Forms.DockStyle.Top; + this.tableLayoutPanelWSVerfolgung.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanelWSVerfolgung.Name = "tableLayoutPanelWSVerfolgung"; + this.tableLayoutPanelWSVerfolgung.RowCount = 2; + this.tableLayoutPanelWSVerfolgung.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanelWSVerfolgung.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanelWSVerfolgung.Size = new System.Drawing.Size(800, 422); + this.tableLayoutPanelWSVerfolgung.TabIndex = 1; + // // FormWSVerfolgung // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -86,7 +86,9 @@ this.KeyPreview = true; this.Name = "FormWSVerfolgung"; this.Text = "WSVerfolgung"; + this.WindowState = System.Windows.Forms.FormWindowState.Maximized; this.Load += new System.EventHandler(this.WSVerfolgung_Load); + this.Shown += new System.EventHandler(this.FormWSVerfolgung_Shown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormWSVerfolgung_KeyDown); this.statusStripWSVerfolgung.ResumeLayout(false); this.statusStripWSVerfolgung.PerformLayout(); diff --git a/AA-Forms/FormWSVerfolgung.cs b/AA-Forms/FormWSVerfolgung.cs index 8ace28c..97b6030 100644 --- a/AA-Forms/FormWSVerfolgung.cs +++ b/AA-Forms/FormWSVerfolgung.cs @@ -32,6 +32,10 @@ namespace Deckungsbeitrag.AA_Forms public FormWSVerfolgung() { InitializeComponent(); + + this.BackColor = Color.Black; + this.WindowState = FormWindowState.Maximized; + this.FormBorderStyle = FormBorderStyle.None; } public FormWSVerfolgung(string userid) : this() { @@ -65,11 +69,10 @@ namespace Deckungsbeitrag.AA_Forms private void WSVerfolgung_Load(object sender, EventArgs e) { - // WaitCursor und Controls ausblenden. + // WaitCursor this.Cursor = Cursors.WaitCursor; - //Funktionen.HideControls(this.Controls); - // StatusStrip DropDown + // StatusStrip DropDown laden. this.toolStripDropDownButtonInfo.DropDownItems.Clear(); List aufgabenliste = Aufgabe.GetList((int)Kategorie.Waschstrasse); foreach(Aufgabe auf in aufgabenliste) @@ -81,65 +84,82 @@ namespace Deckungsbeitrag.AA_Forms } - this.BackColor = Color.Black; - this.WindowState = FormWindowState.Maximized; - this.FormBorderStyle = FormBorderStyle.None; + } + + /// + /// Controls werden hier bevor sie angezeigt werden berechnet. Danach werden sie Eingeblendet und der Cursor auf Default gestellt. + /// + /// + /// + private void FormWSVerfolgung_Shown(object sender, EventArgs e) + { + // Während dem Laden wird das Layout unterdrückt und der Screen ausgeblendet. + this.SuspendLayout(); + this.Visible = false; + + // Größer des TabelPanels anpassen. this.tableLayoutPanelWSVerfolgung.Height = this.statusStripWSVerfolgung.Top; + // Wenn bei Maschine TrocknerKaputt wird Anzahl Fächer um 1 reduziert. if (maschine.TrocknerKaputt) this.tableLayoutPanelWSVerfolgung.RowCount = maschine.Faecher - 1; else this.tableLayoutPanelWSVerfolgung.RowCount = maschine.Faecher; + + // Bei TabelPanel werden die Styles gelöscht und neu ertellt. Gleichmäßige Aufteilung in Prozent. this.tableLayoutPanelWSVerfolgung.RowStyles.Clear(); for (int i = 0; i < tableLayoutPanelWSVerfolgung.RowCount; i++) { tableLayoutPanelWSVerfolgung.RowStyles.Add(new RowStyle(SizeType.Percent, 100f / tableLayoutPanelWSVerfolgung.RowCount)); } - Panel_Laden(1); - //DefaultCursor und Controls einblenden. - //Funktionen.ShowControls(this.Controls); + // TabelPanel laden. + Panel_Laden(true); + + // Layout unterdrücken und Screen einblenden. Cursor wird auf Default gesetzt. + this.Visible = true; + this.ResumeLayout(true); this.Cursor = Cursors.Default; + } - private void AufgabeAuswaehlen_Click(object sender, EventArgs e) - { - ToolStripMenuItem item = (ToolStripMenuItem)sender; - if (((Aufgabe)item.Tag).Bezeichnung == "Extra Kunde") - { - FormNeuerAuftrag neuerAuftrag = new FormNeuerAuftrag(this.Userid); - if (neuerAuftrag.ShowDialog() == DialogResult.OK) - { - this.extraAuftrag = neuerAuftrag.Auftrag; - } - } - this.aufgabe = (Aufgabe)item.Tag; - Fach_speichern(); // Gleiches Fach mit neuem Auftrag = Update. - } - private void Panel_Laden(int start) + /// + /// ScreenControls in Panel von Fachliste laden. + /// + /// Wenn Neustart dann true sonst false. + private void Panel_Laden(bool neustart) { - + + // Fachliste holen damit letzter Auftrag vom Vortag übernommen werden kann. List fachliste = WSFach.GetFachliste(maschine); // Wenn erster Start dann Auftrag aus letztem Fach holen? - if (start == 1) + if (neustart) { + this.fach = new WSFach(); + if (meldung.MaschinenStart() == DialogResult.Yes) { + // Wenn holen, dann Auftrag und aufgabe aus fachliste holen. this.auftrag = Auftrag.GetAuftrag(fachliste[0].AuftragID); this.aufgabe = Aufgabe.GetAufgabe(null, fachliste[0].AufgabeID); - this.fach = new WSFach(); } else { + // Wenn nicht holen, dann Auftrag und Aufgabe enfernen. this.auftrag = null; this.aufgabe = null; + + // Neuen Auftrag eingeben. Wenn kein ExtraKunde wird false als extra weitergegeben. + Open_NeuerAuftrag(false); + + // Fachliste neu laden damit neuer Auftrag in erstes Fach geladen werden kann. + fachliste = WSFach.GetFachliste(maschine); } } // Alle Controls aus dem Panel entfernen. this.tableLayoutPanelWSVerfolgung.Controls.Clear(); - // UserControls mit Daten aus Fachliste in Panel laden. if (fachliste.Count > 0) { @@ -188,7 +208,10 @@ namespace Deckungsbeitrag.AA_Forms } } - ucfach.KundeName = Kunde.GetKunde(null, auftrag.KundeID, null).Suchtext; + // Wenn Kunde hat keinen Suchtext, dann Kundename anzeigen. + if(string.IsNullOrWhiteSpace(Kunde.GetKunde(null, auftrag.KundeID, null).Suchtext))ucfach.KundeName = Kunde.GetKunde(null, auftrag.KundeID, null).KundeName; + else ucfach.KundeName = Kunde.GetKunde(null, auftrag.KundeID, null).Suchtext; + CultureInfo deCult = new CultureInfo("de-DE"); ucfach.LieferTag = ((Liefertag)auftrag.Liefertag.DayOfWeek).ToString(); @@ -198,7 +221,7 @@ namespace Deckungsbeitrag.AA_Forms // Wenn Aufgabe ist ein Extra Kunde. if (aufgabe.Bezeichnung == "Extra Kunde") ucfach.Aufgabe = "Extra Kunde " + Kunde.GetKunde(null, Auftrag.GetAuftrag(fachliste[row].ExtraAuftragID).KundeID, null).Suchtext; else ucfach.Aufgabe = aufgabe.Bezeichnung; - + // Hintergrund des Fachs in der Farbe der Aufgabe. ACHTUNG WEGEN KONTRAST ZU SCHRIFTFARBE. ucfach.BackColor = aufgabe.Farbe; } @@ -207,20 +230,50 @@ namespace Deckungsbeitrag.AA_Forms this.tableLayoutPanelWSVerfolgung.Controls.Add(ucfach, 0, row); } } + } - private void Open_NeuerAuftrag() + /// + /// Wenn eine Info von der Statusleiste gewählt wurde. + /// + /// + /// + private void AufgabeAuswaehlen_Click(object sender, EventArgs e) + { + ToolStripMenuItem item = (ToolStripMenuItem)sender; + + // Aufgabe wird aus dem StatusStripItem geholt. + this.aufgabe = (Aufgabe)item.Tag; + + // Wenn Aufgabe ist ExtraKunde wird NeuerAuftrag geöffnet. + if (((Aufgabe)item.Tag).Bezeichnung == "Extra Kunde") + { + // Wenn ExtraKunde wird true als extra weitergegeben. + Open_NeuerAuftrag(true); + } + Fach_speichern(); // Gleiches Fach mit neuem Auftrag = Update. + } + + /// + /// NeuerAuftrag wird geöffnet und Ergebnis verarbeitet. + /// + /// Wenn ExtraKunde in Fach dann true, sonst false + private void Open_NeuerAuftrag(bool extra) { FormNeuerAuftrag neuerAuftrag = new FormNeuerAuftrag(this.Userid); if (neuerAuftrag.ShowDialog() == DialogResult.OK) { - this.auftrag = neuerAuftrag.Auftrag; + if (extra) this.extraAuftrag = neuerAuftrag.Auftrag; + else this.auftrag = neuerAuftrag.Auftrag; Fach_speichern(); // Gleiches Fach mit neuem Auftrag = Update. } } + + /// + /// Fach wird gespeichert. Bei Änderungen wird Fach überschrieben. Wenn FachID = 0 oder null wird neues Fach erstellt, sonst überschrieben. + /// private void Fach_speichern() { - //this.fach = new WSFach(); this.fach.AuftragID = (int)this.auftrag.AuftragID; this.fach.MaschineID = (int)this.maschine.MaschineID; this.fach.Gewaschen = DateTime.Now; @@ -231,7 +284,7 @@ namespace Deckungsbeitrag.AA_Forms if (this.extraAuftrag != null) this.fach.ExtraAuftragID = this.extraAuftrag.AuftragID; else this.fach.ExtraAuftragID = null; - if (this.fach.Save() == 1) Panel_Laden(2); + if (this.fach.Save() == 1) Panel_Laden(false); } /// @@ -241,8 +294,6 @@ namespace Deckungsbeitrag.AA_Forms /// private void Transport_ValueChanged(object sender, EventArgs e) { - //this.SuspendLayout(); - // Warten bis erster Transport durchgeführt wurde. while (_monitor.WS_1_Transport == true & _monitor.WS_2_Transport == true) { @@ -250,16 +301,21 @@ namespace Deckungsbeitrag.AA_Forms if (_monitor.WS_1_Transport || _monitor.WS_2_Transport) { Maschine ms = (Maschine)this.maschine; + + // Fehlermeldung falls kein Auftrag erstellt wurde. if (this.auftrag != null) { + // Nach Transport wird FachAufgabe und FachExtraAuftrag entfernt da diese nur für ein Fach gelten. this.aufgabe = null; this.extraAuftrag = null; + + // Wenn Fach nicht null ist wird für ein neues Fach die ID entfernt. Dadurch wird bei Save() neues Fach erzeugt. if (this.fach != null) this.fach.FachID = null; - Fach_speichern(); // Neues Fach mit gleichem Inhalt = + Fach_speichern(); } else { - MessageBox.Show($"Kein Auftrag erstellt. LEERFACH wird eingegeben. Bitte in BB1 bearbeiten."); + MessageBox.Show($"Kein Auftrag erstellt. LEERFACH wird eingegeben. Fach bitte im nachhinein bearbeiten."); } //WENN kein Kunde gewählt dann Fach mit KundeID 0. _monitor.WS_2_Transport = _monitor.WS_1_Transport = false; @@ -277,16 +333,24 @@ namespace Deckungsbeitrag.AA_Forms protected override bool ProcessDialogKey(Keys keyData) { //TODO: Umbau in Switch. + + // Escape [ESC] schließt den Screen. if (Form.ModifierKeys == Keys.None && keyData == Keys.Escape) { this.Close(); return true; } + + // Insert [Einfg] öffnet neuen Auftrag. if (Form.ModifierKeys == Keys.None && keyData == Keys.Insert) { - Open_NeuerAuftrag(); + // Neuer Auftrag wird geöffnet. Wenn nicht ExtraKunde wird false weitergegeben, sonst true. + Open_NeuerAuftrag(false); return true; } + + // R-Taste [R] simuliert Transport. Sollte wenn SPS angeschlossen ist nicht mehr notwendig sein und deaktiviert werden. + //TODO: Deaktivieren wenn SPS funktioniert. Transport wird simuliert. if (Form.ModifierKeys == Keys.None && keyData == Keys.R) { Cursor.Current = Cursors.WaitCursor; @@ -322,5 +386,6 @@ namespace Deckungsbeitrag.AA_Forms toolStripDropDownButtonInfo.DropDown.Show(); } } + } } diff --git a/AA-Klassen/Fehlermeldungen.cs b/AA-Klassen/Fehlermeldungen.cs index 600c84d..13fcef8 100644 --- a/AA-Klassen/Fehlermeldungen.cs +++ b/AA-Klassen/Fehlermeldungen.cs @@ -278,7 +278,7 @@ namespace DatenDB { DialogResult result = DialogResult.Cancel; - string s = $"Möchtest du den Auftrag des letzten Faches wiederherstellen?"; + string s = $"Möchtest du den Auftrag des letzten Faches wiederherstellen? Wenn NEIN erstelle einen neuen Auftrag."; string caption = "ACHTUNG"; MessageBoxButtons buttons = MessageBoxButtons.YesNo; MessageBoxIcon icon = MessageBoxIcon.Exclamation; diff --git a/App.config b/App.config index 79ad880..638466a 100644 --- a/App.config +++ b/App.config @@ -6,7 +6,7 @@ - + diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 06b25f7..5df6570 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -90,6 +90,16 @@ namespace Deckungsbeitrag.Properties { } } + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Exclamation_Red { + get { + object obj = ResourceManager.GetObject("Exclamation_Red", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index 74795fc..f4ca72a 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -142,4 +142,7 @@ ..\Resources\WarningRule_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\weather_warning_signal_alert_exclamation_icon_124159.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Resources/weather_warning_signal_alert_exclamation_icon_124159.png b/Resources/weather_warning_signal_alert_exclamation_icon_124159.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae658a0d14830e6d349ee49ecb6b86bd1bd3576 GIT binary patch literal 18778 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 HN@xNA2IL<= literal 0 HcmV?d00001