using System; using System.Drawing; using System.Windows.Forms; namespace DataTableParsingEngine { public class TableGroupParser { /// /// Paints rows according to their RowAttribute and detects whether or not they are part of a group. /// This function offers a faster method of determining all of this by starting at the row index that /// fired the row leave even. As opposed to the PaintRowGroups function which spins through all the /// DataGridView's rows. /// /// The DataGridView to parse. /// The starting index (the row that fired the RowLeave event) /// True to force a full scan of all rows beginning at the starting index. public static bool PaintRowGroupss(DataGridView table, int startingIndex, bool fullScan = false) { var parser = new RowParser(); var isHeaderColumn = 1;//(int) SalesTableColumns.IsHeaderRow; var isMemberColumn = 2;//(int) SalesTableColumns.IsMemberRow; var isDirtyColumn = (int) SalesTableColumns.IsDirty; var updatesOccured = false; if (table.ColumnCount < Enum.GetNames(typeof(SalesTableColumns)).Length) { isHeaderColumn = 2;//(int) InventoryTableColumns.IsHeaderRow; isMemberColumn = 5;//(int) InventoryTableColumns.IsMemberRow; isDirtyColumn = (int) InventoryTableColumns.IsDirty; } //Spin through the dataGridView rows starting at the row that fired the event. for (var i = startingIndex; i < (table.RowCount - 1); i++) { //Get the status of the current row. var currentRowAttribute = parser.GetRowAttribute(table.Rows[i]); //Get the previous row's status. var previousRow = RowParser.RowAttribute.UnAssigned; if (i > 0) { previousRow = parser.GetRowAttribute(table.Rows[i - 1]); } //Get the next row's attribute. var nextRow = RowParser.RowAttribute.UnAssigned; if ((i + 1) < table.RowCount) { nextRow = parser.GetRowAttribute(table.Rows[i + 1]); } //If current row is a header row... if (currentRowAttribute == RowParser.RowAttribute.HeaderRow) { //...and the current row is index zero or the previous row is a header row //then clear color coding from both. if (previousRow == RowParser.RowAttribute.HeaderRow) { //Check the previous row's attributes to see if it needs to be marked for updating. if ((bool) table.Rows[i - 1].Cells[isHeaderColumn].EditedFormattedValue || (bool) table.Rows[i - 1].Cells[isMemberColumn].EditedFormattedValue) { //The previous row had some attributes set, so mark the previous row for updating. table.Rows[i - 1].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i - 1].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i - 1].DefaultCellStyle.BackColor = default(Color); } //Clear the previous row of its attributes. table.Rows[i - 1].Cells[isHeaderColumn].Value = false; table.Rows[i - 1].Cells[isMemberColumn].Value = false; //This condition means the user changed the members of a group, so the old header row needs to be updated in the database. //Check the next row to see if its a member row before declaring the current row a header row. if (nextRow == RowParser.RowAttribute.MemberRow) { if (!(bool)table.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool) table.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the previous row for updating. table.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } //Set the current row as a header row. table.Rows[i].Cells[isHeaderColumn].Value = true; table.Rows[i].Cells[isMemberColumn].Value = false; table.Rows[i].DefaultCellStyle.BackColor = TableColors.HeaderRow; //Mark the next row as a member row. if ((bool) table.Rows[i + 1].Cells[isHeaderColumn].EditedFormattedValue || !(bool)table.Rows[i + 1].Cells[isMemberColumn].EditedFormattedValue) { //The next row had some attributes set, so mark the previous row for updating. table.Rows[i + 1].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i + 1].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i + 1].DefaultCellStyle.BackColor = default(Color); } table.Rows[i + 1].Cells[isHeaderColumn].Value = false; table.Rows[i + 1].Cells[isMemberColumn].Value = true; table.Rows[i + 1].DefaultCellStyle.BackColor = TableColors.MemberRow; } else { //If the current row is not a member row then clear the current row of any attributes it may have. if ((bool) table.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool) table.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the previous row for updating. table.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } //Clear the current row's attributes. table.Rows[i].Cells[isHeaderColumn].Value = false; table.Rows[i].Cells[isMemberColumn].Value = false; table.Rows[i].DefaultCellStyle.BackColor = default(Color); if (!fullScan) return updatesOccured; } } else { //Else if check to see if the previous row exists. if (previousRow == RowParser.RowAttribute.UnAssigned) { //This indicates that there is no previous row, so its safe to assume that //we can simply continue on to the next row. continue; } if (nextRow == RowParser.RowAttribute.MemberRow) { continue; } //If the current row is not a member row then clear the current row of any attributes it may have. if ((bool)table.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)table.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the previous row for updating. table.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } //Clear the current row's attributes. table.Rows[i].Cells[isHeaderColumn].Value = false; table.Rows[i].Cells[isMemberColumn].Value = false; table.Rows[i].DefaultCellStyle.BackColor = default(Color); if(!fullScan) return updatesOccured; } } if (currentRowAttribute == RowParser.RowAttribute.MemberRow) { //Check to see if the previous row is a header row. if (previousRow == RowParser.RowAttribute.HeaderRow) { //Set the previous row as a header. if (!(bool)table.Rows[i - 1].Cells[isHeaderColumn].EditedFormattedValue || (bool)table.Rows[i - 1].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. table.Rows[i - 1].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i - 1].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i - 1].DefaultCellStyle.BackColor = default(Color); } table.Rows[i - 1].Cells[isHeaderColumn].Value = true; table.Rows[i - 1].Cells[isMemberColumn].Value = false; table.Rows[i - 1].DefaultCellStyle.BackColor = TableColors.HeaderRow; //Mark current row as member row. if ((bool)table.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || !(bool)table.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. table.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } table.Rows[i].Cells[isHeaderColumn].Value = false; table.Rows[i].Cells[isMemberColumn].Value = true; table.Rows[i].DefaultCellStyle.BackColor = TableColors.MemberRow; } else if (previousRow == RowParser.RowAttribute.MemberRow) { //Check to see if the previous row is set as a member row. if ((bool) table.Rows[i - 1].Cells[isMemberColumn].EditedFormattedValue) { //Assume that the current row is part of the group. if ((bool) table.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || !(bool) table.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. table.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } table.Rows[i].Cells[isHeaderColumn].Value = false; table.Rows[i].Cells[isMemberColumn].Value = true; table.Rows[i].DefaultCellStyle.BackColor = TableColors.MemberRow; } else { if ((bool)table.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)table.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. table.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } table.Rows[i].Cells[isHeaderColumn].Value = false; table.Rows[i].Cells[isMemberColumn].Value = false; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } } else { if ((bool)table.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)table.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. table.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; table.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; table.Rows[i].DefaultCellStyle.BackColor = default(Color); } table.Rows[i].Cells[isHeaderColumn].Value = false; table.Rows[i].Cells[isMemberColumn].Value = false; } } } return updatesOccured; } public static bool PaintIneventorys(DataGridView inventoryDataGridView, DataGridView masterGridView, int startingIndex, bool fullScan = false) { var parser = new RowParser(); var updatesOccured = false; const int isHeaderColumn = 2; const int isMemberColumn = 1; const int isDirtyColumn = (int)InventoryTableColumns.IsDirty; //Spin through the dataGridView rows starting at the row that fired the event. for (var i = startingIndex; i < (inventoryDataGridView.RowCount - 1); i++) { //Get the status of the current row. var masterCurrentRow = parser.GetRowAttribute(masterGridView.Rows[i]); //var inventoryCurrentRow = parser.GetRowAttribute(inventoryDataGridView.Rows[i]); //Get the previous row's status. var masterPreviousRow = RowParser.RowAttribute.UnAssigned; //var inventoryPreviousRow = RowParser.RowAttribute.UnAssigned; if (i > 0) { masterPreviousRow = parser.GetRowAttribute(masterGridView.Rows[i - 1]); //inventoryPreviousRow = parser.GetRowAttribute(inventoryDataGridView.Rows[i - 1]); } //Get the next row's attribute. var masterNextRow = RowParser.RowAttribute.UnAssigned; //var inventoryNextRow = RowParser.RowAttribute.UnAssigned; if ((i + 1) < inventoryDataGridView.RowCount) { masterNextRow = parser.GetRowAttribute(masterGridView.Rows[i + 1]); //inventoryNextRow = parser.GetRowAttribute(inventoryDataGridView.Rows[i + 1]); } //If current row is a header row... if (masterCurrentRow == RowParser.RowAttribute.HeaderRow) { //...and the current row is index zero or the previous row is a header row //then clear color coding from both. if (masterPreviousRow == RowParser.RowAttribute.HeaderRow) { //Check the previous row's attributes to see if it needs to be marked for updating. if ((bool)inventoryDataGridView.Rows[i - 1].Cells[isHeaderColumn].EditedFormattedValue || (bool)inventoryDataGridView.Rows[i - 1].Cells[isMemberColumn].EditedFormattedValue) { //The previous row had some attributes set, so mark the previous row for updating. inventoryDataGridView.Rows[i - 1].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i - 1].HeaderCell.Style.BackColor = TableColors.PendingEdit; inventoryDataGridView.Rows[i - 1].DefaultCellStyle.BackColor = default(Color); } //Clear the previous row of its attributes. inventoryDataGridView.Rows[i - 1].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i - 1].Cells[isMemberColumn].Value = false; //This condition means the user changed the members of a group, so the old header row needs to be updated in the database. //Check the next row to see if its a member row before declaring the current row a header row. if (masterNextRow == RowParser.RowAttribute.MemberRow)// && inventoryNextRow == RowParser.RowAttribute.MemberRow) { if (!(bool)inventoryDataGridView.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)inventoryDataGridView.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the previous row for updating. inventoryDataGridView.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = default(Color); } //Set the current row as a header row. inventoryDataGridView.Rows[i].Cells[isHeaderColumn].Value = true; inventoryDataGridView.Rows[i].Cells[isMemberColumn].Value = false; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = TableColors.HeaderRow; //Mark the next row as a member row. if ((bool)inventoryDataGridView.Rows[i + 1].Cells[isHeaderColumn].EditedFormattedValue || !(bool)inventoryDataGridView.Rows[i + 1].Cells[isMemberColumn].EditedFormattedValue) { //The next row had some attributes set, so mark the previous row for updating. inventoryDataGridView.Rows[i + 1].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i + 1].HeaderCell.Style.BackColor = TableColors.PendingEdit; } inventoryDataGridView.Rows[i + 1].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i + 1].Cells[isMemberColumn].Value = true; inventoryDataGridView.Rows[i + 1].DefaultCellStyle.BackColor = TableColors.MemberRow; } else { //If the current row is not a member row then clear the current row of any attributes it may have. if ((bool)inventoryDataGridView.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)inventoryDataGridView.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the previous row for updating. inventoryDataGridView.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; } //Clear the current row's attributes. inventoryDataGridView.Rows[i].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i].Cells[isMemberColumn].Value = false; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = default(Color); if (!fullScan) return updatesOccured; } } else { //Else if check to see if the previous row exists. if (masterPreviousRow == RowParser.RowAttribute.UnAssigned) { //This indicates that there is no previous row, so its safe to assume that //we can simply continue on to the next row. continue; } if (masterNextRow == RowParser.RowAttribute.MemberRow) { continue; } //If the current row is not a member row then clear the current row of any attributes it may have. if ((bool)inventoryDataGridView.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)inventoryDataGridView.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the previous row for updating. inventoryDataGridView.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; } //Clear the current row's attributes. inventoryDataGridView.Rows[i].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i].Cells[isMemberColumn].Value = false; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = default(Color); if (!fullScan) return updatesOccured; } } if (masterCurrentRow == RowParser.RowAttribute.MemberRow)// && inventoryCurrentRow == RowParser.RowAttribute.MemberRow) { //Check to see if the previous row is a header row. if (masterPreviousRow == RowParser.RowAttribute.HeaderRow) { //Set the previous row as a header. if (!(bool)inventoryDataGridView.Rows[i - 1].Cells[isHeaderColumn].EditedFormattedValue || (bool)inventoryDataGridView.Rows[i - 1].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. inventoryDataGridView.Rows[i - 1].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i - 1].HeaderCell.Style.BackColor = TableColors.PendingEdit; } inventoryDataGridView.Rows[i - 1].Cells[isHeaderColumn].Value = true; inventoryDataGridView.Rows[i - 1].Cells[isMemberColumn].Value = false; inventoryDataGridView.Rows[i - 1].DefaultCellStyle.BackColor = TableColors.HeaderRow; //Mark current row as member row. if ((bool)inventoryDataGridView.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || !(bool)inventoryDataGridView.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. inventoryDataGridView.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; } inventoryDataGridView.Rows[i].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i].Cells[isMemberColumn].Value = true; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = TableColors.MemberRow; } else if (masterPreviousRow == RowParser.RowAttribute.MemberRow) { //Check to see if the previous row is set as a member row. if ((bool)inventoryDataGridView.Rows[i - 1].Cells[isMemberColumn].EditedFormattedValue) { //Assume that the current row is part of the group. if ((bool)inventoryDataGridView.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || !(bool)inventoryDataGridView.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. inventoryDataGridView.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; } inventoryDataGridView.Rows[i].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i].Cells[isMemberColumn].Value = true; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = TableColors.MemberRow; } else { if ((bool)inventoryDataGridView.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)inventoryDataGridView.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. inventoryDataGridView.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; } inventoryDataGridView.Rows[i].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i].Cells[isMemberColumn].Value = false; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = default(Color); } } else { if ((bool)inventoryDataGridView.Rows[i].Cells[isHeaderColumn].EditedFormattedValue || (bool)inventoryDataGridView.Rows[i].Cells[isMemberColumn].EditedFormattedValue) { //The current row had some attributes set, so mark the current row for updating. inventoryDataGridView.Rows[i].Cells[isDirtyColumn].Value = true; updatesOccured = true; inventoryDataGridView.Rows[i].HeaderCell.Style.BackColor = TableColors.PendingEdit; inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = default(Color); } inventoryDataGridView.Rows[i].Cells[isHeaderColumn].Value = false; inventoryDataGridView.Rows[i].Cells[isMemberColumn].Value = false; } } } return updatesOccured; } public enum SalesTableColumns { Id = 0, AdItem = 1, Sold = 2, SalePrice = 3, TotalSales = 4, Cost = 5, ProfitReturn = 6, TotalProfitReturn = 7, IsDirty = 8 } public enum InventoryTableColumns { Id = 0, AdItem = 1, BeginningInventory = 2, Recieved = 3, Total = 4, EndingInventory = 5, IsDirty = 6 } public enum InvoiceTableColumns { Id = 0, InvoiceDate = 1, Supplier = 2, InvoiceNumber = 3, InvoiceNetAmountAtCost = 4, InvoiceNote = 5, IsDirty = 6 } } }