/// <summary> /// Loads the default configuration. /// </summary> /// <param name="Grid">The grid.</param> private void LoadDefaultConfiguration(JDHSoftware.Krypton.Toolkit.KryptonOutlookGrid.KryptonOutlookGrid Grid) { Grid.ClearEverything(); Grid.GroupBox.Visible = true; Grid.HideColumnOnGrouping = false; Grid.FillMode = FillMode.GroupsAndNodes; //treemode enabled; Grid.ShowLines = true; activeColumns = new SandBoxGridColumn[] { SandBoxGridColumn.ColumnCustomerID, SandBoxGridColumn.ColumnCustomerName, SandBoxGridColumn.ColumnAddress, SandBoxGridColumn.ColumnCity, SandBoxGridColumn.ColumnCountry, SandBoxGridColumn.ColumnOrderDate, SandBoxGridColumn.ColumnProduct, SandBoxGridColumn.ColumnPrice, SandBoxGridColumn.SatisfactionColumn, SandBoxGridColumn.ColumnToken }; DataGridViewColumn[] columnsToAdd = new DataGridViewColumn[10] { SetupColumn(SandBoxGridColumn.ColumnCustomerID), SetupColumn(SandBoxGridColumn.ColumnCustomerName), SetupColumn(SandBoxGridColumn.ColumnAddress), SetupColumn(SandBoxGridColumn.ColumnCity), SetupColumn(SandBoxGridColumn.ColumnCountry), SetupColumn(SandBoxGridColumn.ColumnOrderDate), SetupColumn(SandBoxGridColumn.ColumnProduct), SetupColumn(SandBoxGridColumn.ColumnPrice), SetupColumn(SandBoxGridColumn.SatisfactionColumn), SetupColumn(SandBoxGridColumn.ColumnToken) }; Grid.Columns.AddRange(columnsToAdd); //Define the columns for a possible grouping Grid.AddInternalColumn(columnsToAdd[0], new OutlookGridDefaultGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[1], new OutlookGridAlphabeticGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[2], new OutlookGridDefaultGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[3], new OutlookGridDefaultGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[4], new OutlookGridDefaultGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[5], new OutlookGridDateTimeGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[6], new OutlookGridDefaultGroup(null) { OneItemText = "1 product", XXXItemsText = " products" }, SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[7], new OutlookGridPriceGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[8], new OutlookGridDefaultGroup(null), SortOrder.None, -1, -1); Grid.AddInternalColumn(columnsToAdd[9], new OutlookGridDefaultGroup(null), SortOrder.None, -1, -1); //Add a default conditionnal formatting ConditionalFormatting cond = new ConditionalFormatting(); cond.ColumnName = SandBoxGridColumn.ColumnPrice.ToString(); cond.FormatType = EnumConditionalFormatType.TwoColorsRange; cond.FormatParams = new TwoColorsParams(Color.White, Color.FromArgb(255, 255, 58, 61)); Grid.ConditionalFormatting.Add(cond); }
/// <summary> /// this function checks if the user hit the expand (+) or collapse (-) icon. /// if it was hit it will return true /// </summary> /// <param name="e">mouse click event arguments</param> /// <returns>returns true if the icon was hit, false otherwise</returns> internal bool IsIconHit(DataGridViewCellMouseEventArgs e) { if (e.ColumnIndex < 0) { return(false); } if (!isGroupRow) { return(false); } KryptonOutlookGrid grid = (KryptonOutlookGrid)DataGridView; Rectangle rowBounds = grid.GetRowDisplayRectangle(Index, false); int rowHeadersWidth = grid.RowHeadersVisible ? grid.RowHeadersWidth : 0; int l = e.X + grid.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Left; if (isGroupRow && (l >= rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + group.Level * StaticValues._groupLevelMultiplier) && (l <= rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + group.Level * StaticValues._groupLevelMultiplier + 11) && (e.Y >= rowBounds.Height - 18) && (e.Y <= rowBounds.Height - 7)) { return(true); } return(false); }
/// <summary> /// Upgrades the grid configuration to vx. /// </summary> /// <param name="doc">The document.</param> /// <param name="version">The version.</param> /// <param name="Grid">The grid.</param> /// <param name="state">The state.</param> private void UpgradeGridConfigToVX(XDocument doc, int version, JDHSoftware.Krypton.Toolkit.KryptonOutlookGrid.KryptonOutlookGrid Grid, LoadState state) { //Do changes according to version //For example you can add automatically new columns. This can be useful when you update your application to add columns and would like to display them to the user for the first time. //switch (version) //{ //case 2: // // Do changes to match the V2 // if (state == DataGridViewSetup.LoadState.Before) // { // doc.Element("OutlookGrid").Attribute("V").Value = version.ToString(); // Array.Resize(ref activeColumns, activeColumns.Length + 1); // DataGridViewColumn columnToAdd = SetupColumn(SandBoxGridColumn.ColumnPrice2); // Grid.Columns.Add(columnToAdd); // Grid.AddInternalColumn(columnToAdd, new OutlookGridDefaultGroup(null) // { // OneItemText = "Example", // XXXItemsText = "Examples" // }, SortOrder.None, -1, -1); // activeColumns[activeColumns.Length - 1] = SandBoxGridColumn.ColumnPrice2; // Grid.PersistConfiguration(PublicFcts.GetGridConfigFile, version); // } // break; //} }
/// <summary> /// Checks the and upgrade configuration file. /// </summary> /// <param name="versionGrid">The version grid.</param> /// <param name="doc">The document.</param> /// <param name="grid">The grid.</param> /// <param name="state">The state.</param> private void CheckAndUpgradeConfigFile(int versionGrid, XDocument doc, JDHSoftware.Krypton.Toolkit.KryptonOutlookGrid.KryptonOutlookGrid grid, LoadState state) { while (versionGrid < StaticInfos._GRIDCONFIG_VERSION) { UpgradeGridConfigToVX(doc, versionGrid + 1, grid, state); versionGrid += 1; } }
/// <summary> /// Setups the data grid view. /// </summary> /// <param name="Grid">The grid.</param> /// <param name="RestoreIfPossible">if set to <c>true</c> [restore if possible].</param> public void SetupDataGridView(JDHSoftware.Krypton.Toolkit.KryptonOutlookGrid.KryptonOutlookGrid Grid, bool RestoreIfPossible) { if (File.Exists(Application.StartupPath + "/grid.xml") & RestoreIfPossible) { try { LoadConfigFromFile(Application.StartupPath + "/grid.xml", Grid); } catch (Exception ex) { KryptonMessageBox.Show("Error when retrieving configuration : " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Grid.ClearEverything(); LoadDefaultConfiguration(Grid); } } else { LoadDefaultConfiguration(Grid); } }
//internal bool IsNodeIconHit(DataGridViewCellMouseEventArgs e) //{ // if (e.ColumnIndex < 0) return false; // if (!this.HasChildren) return false; // DataGridViewCell cell = this.Cells[e.ColumnIndex]; // if (cell.GetType() is KryptonDataGridViewTreeTextCell) { // cell. // } // KryptonOutlookGrid grid = (KryptonOutlookGrid)this.DataGridView; // Rectangle glyphRect = new Rectangle(rect.X + this.GlyphMargin, rect.ContentBounds.Y, INDENT_WIDTH, this.ContentBounds.Height - 1); // if ((e.X <= glyphRect.X + 11) && // (e.X >= glyphRect.X) && // (e.Y >= glyphRect.Y + (glyphRect.Height / 2) - 4) && // (e.Y <= glyphRect.Y + (glyphRect.Height / 2) - 4 + 11)) // if (this.isGroupRow && // (l >= rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + group.Level * StaticValues._groupLevelMultiplier) && // (l <= rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + group.Level * StaticValues._groupLevelMultiplier + 11) && // (e.Y >= rowBounds.Height - 18) && // (e.Y <= rowBounds.Height - 7)) // return true; // return false; //} internal bool IsGroupImageHit(DataGridViewCellMouseEventArgs e) { if (e.ColumnIndex < 0) { return(false); } if (!isGroupRow || group.GroupImage == null) { return(false); } KryptonOutlookGrid grid = (KryptonOutlookGrid)DataGridView; Rectangle rowBounds = grid.GetRowDisplayRectangle(Index, false); int rowHeadersWidth = grid.RowHeadersVisible ? grid.RowHeadersWidth : 0; int l = e.X + grid.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Left; int offsetHeight; if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2013) { offsetHeight = StaticValues._2013OffsetHeight; } else { offsetHeight = StaticValues._defaultOffsetHeight; } if (isGroupRow && (l >= rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 18 + group.Level * StaticValues._groupLevelMultiplier) && (l <= rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 18 + group.Level * StaticValues._groupLevelMultiplier + 16) && (e.Y >= rowBounds.Height - offsetHeight) && (e.Y <= rowBounds.Height - 6)) { return(true); } return(false); }
/// <summary> /// the main difference with a Group row and a regular row is the way it is painted on the control. /// the Paint method is therefore overridden and specifies how the Group row is painted. /// Note: this method is not implemented optimally. It is merely used for demonstration purposes /// </summary> /// <param name="graphics"></param> /// <param name="clipBounds"></param> /// <param name="rowBounds"></param> /// <param name="rowIndex"></param> /// <param name="rowState"></param> /// <param name="isFirstDisplayedRow"></param> /// <param name="isLastVisibleRow"></param> protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow) { if (isGroupRow) { KryptonOutlookGrid grid = (KryptonOutlookGrid)DataGridView; int rowHeadersWidth = grid.RowHeadersVisible ? grid.RowHeadersWidth : 0; int groupLevelIndentation = group.Level * StaticValues._groupLevelMultiplier; int gridwidth = grid.Columns.GetColumnsWidth(DataGridViewElementStates.Visible); Rectangle myRowBounds = rowBounds; myRowBounds.Width = gridwidth; IPaletteBack paletteBack = grid.StateNormal.DataCell.Back; IPaletteBorder paletteBorder = grid.StateNormal.DataCell.Border; PaletteState state = PaletteState.Normal; if (grid.PreviousSelectedGroupRow == rowIndex && (KryptonManager.CurrentGlobalPalette.GetRenderer() != KryptonManager.RenderOffice2013)) { state = PaletteState.CheckedNormal; } using (RenderContext renderContext = new RenderContext(grid, graphics, myRowBounds, grid.Renderer)) { using (GraphicsPath path = grid.Renderer.RenderStandardBorder.GetBackPath(renderContext, myRowBounds, paletteBorder, VisualOrientation.Top, PaletteState.Normal)) { //Back IDisposable unused = grid.Renderer.RenderStandardBack.DrawBack(renderContext, myRowBounds, path, paletteBack, VisualOrientation.Top, state, null); // We never save the memento for reuse later if (unused != null) { unused.Dispose(); unused = null; } } } // Draw the botton : solid line for 2007 palettes or dot line for 2010 palettes, full background for 2013 if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2010) { using (Pen focusPen = new Pen(Color.Gray)) { focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; graphics.DrawLine(focusPen, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset, rowBounds.Bottom - 1, gridwidth + 1, rowBounds.Bottom - 1); } } else if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2013) { using (SolidBrush br = new SolidBrush(Color.FromArgb(225, 225, 225))) { graphics.FillRectangle(br, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset, rowBounds.Bottom - StaticValues._2013GroupRowHeight, gridwidth + 1, StaticValues._2013GroupRowHeight - 1); } } else { using (SolidBrush br = new SolidBrush(paletteBorder.GetBorderColor1(state))) { graphics.FillRectangle(br, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset, rowBounds.Bottom - 2, gridwidth + 1, 2); } } //Draw right vertical bar if (grid.CellBorderStyle == DataGridViewCellBorderStyle.SingleVertical || grid.CellBorderStyle == DataGridViewCellBorderStyle.Single) { using (SolidBrush br = new SolidBrush(paletteBorder.GetBorderColor1(state))) { graphics.FillRectangle(br, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + gridwidth, rowBounds.Top, 1, rowBounds.Height); } } //Set the icon and lines according to the renderer if (group.Collapsed) { if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2010 || KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2013) { graphics.DrawImage(Properties.Resources.collapseIcon2010, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + groupLevelIndentation, rowBounds.Bottom - 18, 11, 11); } else { graphics.DrawImage(Properties.Resources.expandIcon, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + groupLevelIndentation, rowBounds.Bottom - 18, 11, 11); } } else { if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2010 || KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2013) { graphics.DrawImage(Properties.Resources.expandIcon2010, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + groupLevelIndentation, rowBounds.Bottom - 18, 11, 11); } else { graphics.DrawImage(Properties.Resources.collapseIcon, rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + groupLevelIndentation, rowBounds.Bottom - 18, 11, 11); } } //Draw image group int imageoffset = 0; if (group.GroupImage != null) { if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2010 || KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2013) { graphics.DrawImage(group.GroupImage, rowHeadersWidth - grid.HorizontalScrollingOffset + StaticValues._ImageOffsetwidth + groupLevelIndentation, rowBounds.Bottom - StaticValues._2013OffsetHeight, StaticValues._groupImageSide, StaticValues._groupImageSide); imageoffset = StaticValues._ImageOffsetwidth; } else { graphics.DrawImage(group.GroupImage, rowHeadersWidth - grid.HorizontalScrollingOffset + StaticValues._ImageOffsetwidth + groupLevelIndentation, rowBounds.Bottom - StaticValues._defaultOffsetHeight, StaticValues._groupImageSide, StaticValues._groupImageSide); imageoffset = StaticValues._ImageOffsetwidth; } } //Draw text, using the current grid font int offsetText = rowHeadersWidth - grid.HorizontalScrollingOffset + 18 + imageoffset + groupLevelIndentation; if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2013) { TextRenderer.DrawText(graphics, group.Text, grid.GridPalette.GetContentShortTextFont(PaletteContentStyle.LabelBoldControl, state), new Rectangle(offsetText, rowBounds.Bottom - StaticValues._2013OffsetHeight, rowBounds.Width - offsetText, rowBounds.Height), grid.GridPalette.GetContentShortTextColor1(PaletteContentStyle.LabelNormalControl, state), TextFormatFlags.EndEllipsis | TextFormatFlags.SingleLine | TextFormatFlags.PreserveGraphicsClipping); } else { TextRenderer.DrawText(graphics, group.Text, grid.GridPalette.GetContentShortTextFont(PaletteContentStyle.LabelBoldControl, state), new Rectangle(offsetText, rowBounds.Bottom - StaticValues._defaultOffsetHeight, rowBounds.Width - offsetText, rowBounds.Height), grid.GridPalette.GetContentShortTextColor1(PaletteContentStyle.LabelNormalControl, state), TextFormatFlags.EndEllipsis | TextFormatFlags.SingleLine | TextFormatFlags.PreserveGraphicsClipping); } ////Debug Hits ////ExpandCollaspe icon //graphics.DrawRectangle(new Pen(Color.Red), new Rectangle(rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + 4 + group.Level * 15, rowBounds.Bottom - 18, 11, 11)); ////Image //if (KryptonManager.CurrentGlobalPalette.GetRenderer() == KryptonManager.RenderOffice2013) // graphics.DrawRectangle(new Pen(Color.Blue), new Rectangle(rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + StaticValues._ImageOffsetwidth + groupLevelIndentation, rowBounds.Bottom - StaticValues._2013OffsetHeight, StaticValues._groupImageSide, StaticValues._groupImageSide)); //else // graphics.DrawRectangle(new Pen(Color.Blue), new Rectangle(rowBounds.Left + rowHeadersWidth - grid.HorizontalScrollingOffset + StaticValues._ImageOffsetwidth + groupLevelIndentation, rowBounds.Bottom - StaticValues._defaultOffsetHeight, StaticValues._groupImageSide, StaticValues._groupImageSide)); } else { base.Paint(graphics, clipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow); } }
/// <summary> /// Loads the configuration from file. /// </summary> /// <param name="file">The file.</param> /// <param name="Grid">The grid.</param> private void LoadConfigFromFile(string file, JDHSoftware.Krypton.Toolkit.KryptonOutlookGrid.KryptonOutlookGrid Grid) { if (string.IsNullOrEmpty(file)) { throw new Exception("Grid config file is missing !"); } XDocument doc = XDocument.Load(file); int versionGrid = -1; int.TryParse(doc.Element("OutlookGrid").Attribute("V").Value, out versionGrid); //Upgrade if necessary the config file CheckAndUpgradeConfigFile(versionGrid, doc, Grid, LoadState.Before); Grid.ClearEverything(); Grid.GroupBox.Visible = CommonHelper.StringToBool(doc.XPathSelectElement("OutlookGrid/GroupBox").Value); Grid.HideColumnOnGrouping = CommonHelper.StringToBool(doc.XPathSelectElement("OutlookGrid/HideColumnOnGrouping").Value); //Initialize int NbColsInFile = doc.XPathSelectElements("//Column").Count(); DataGridViewColumn[] columnsToAdd = new DataGridViewColumn[NbColsInFile]; SandBoxGridColumn[] enumCols = new SandBoxGridColumn[NbColsInFile]; OutlookGridColumn[] OutlookColumnsToAdd = new OutlookGridColumn[columnsToAdd.Length]; SortedList <int, int> hash = new SortedList <int, int>();// (DisplayIndex , Index) int i = 0; IOutlookGridGroup group; XElement node2; foreach (XElement node in doc.XPathSelectElement("OutlookGrid/Columns").Nodes()) { //Create the columns and restore the saved properties //As the OutlookGrid receives constructed DataGridViewColumns, only the parent application can recreate them (dgvcolumn not serializable) enumCols[i] = (SandBoxGridColumn)Enum.Parse(typeof(SandBoxGridColumn), node.Element("Name").Value); columnsToAdd[i] = SetupColumn(enumCols[i]); columnsToAdd[i].Width = int.Parse(node.Element("Width").Value); columnsToAdd[i].Visible = CommonHelper.StringToBool(node.Element("Visible").Value); hash.Add(int.Parse(node.Element("DisplayIndex").Value), i); //Reinit the group if it has been set previously group = null; if (!node.Element("GroupingType").IsEmpty&& node.Element("GroupingType").HasElements) { node2 = node.Element("GroupingType"); group = (IOutlookGridGroup)Activator.CreateInstance(Type.GetType(TypeConverter.ProcessType(node2.Element("Name").Value), true)); group.OneItemText = node2.Element("OneItemText").Value; group.XXXItemsText = node2.Element("XXXItemsText").Value; group.SortBySummaryCount = CommonHelper.StringToBool(node2.Element("SortBySummaryCount").Value); if (!string.IsNullOrEmpty((node2.Element("ItemsComparer").Value))) { Object comparer = Activator.CreateInstance(Type.GetType(TypeConverter.ProcessType(node2.Element("ItemsComparer").Value), true)); group.ItemsComparer = (IComparer)comparer; } if (node2.Element("Name").Value.Contains("OutlookGridDateTimeGroup")) { ((OutlookGridDateTimeGroup)group).Interval = (OutlookGridDateTimeGroup.DateInterval)Enum.Parse(typeof(OutlookGridDateTimeGroup.DateInterval), node2.Element("GroupDateInterval").Value); } } OutlookColumnsToAdd[i] = new OutlookGridColumn(columnsToAdd[i], group, (SortOrder)Enum.Parse(typeof(SortOrder), node.Element("SortDirection").Value), int.Parse(node.Element("GroupIndex").Value), int.Parse(node.Element("SortIndex").Value)); i += 1; } //First add the underlying DataGridViewColumns to the grid Grid.Columns.AddRange(columnsToAdd); //And then the outlookgrid columns Grid.AddRangeInternalColumns(OutlookColumnsToAdd); //Add conditionnal formatting to the grid EnumConditionalFormatType conditionFormatType = default(EnumConditionalFormatType); IFormatParams conditionFormatParams = default(IFormatParams); foreach (XElement node in doc.XPathSelectElement("OutlookGrid/ConditionalFormatting").Nodes()) { conditionFormatType = (EnumConditionalFormatType)Enum.Parse(typeof(EnumConditionalFormatType), node.Element("FormatType").Value); XElement nodeParams = node.Element("FormatParams"); switch (conditionFormatType) { case EnumConditionalFormatType.Bar: conditionFormatParams = new BarParams(Color.FromArgb(int.Parse(nodeParams.Element("BarColor").Value)), CommonHelper.StringToBool(nodeParams.Element("GradientFill").Value)); break; case EnumConditionalFormatType.ThreeColorsRange: conditionFormatParams = new ThreeColorsParams(Color.FromArgb(int.Parse(nodeParams.Element("MinimumColor").Value)), Color.FromArgb(int.Parse(nodeParams.Element("MediumColor").Value)), Color.FromArgb(int.Parse(nodeParams.Element("MaximumColor").Value))); break; case EnumConditionalFormatType.TwoColorsRange: conditionFormatParams = new TwoColorsParams(Color.FromArgb(int.Parse(nodeParams.Element("MinimumColor").Value)), Color.FromArgb(int.Parse(nodeParams.Element("MaximumColor").Value))); break; default: conditionFormatParams = null; //will never happened but who knows ? throw exception ? break; } Grid.ConditionalFormatting.Add(new ConditionalFormatting(node.Element("ColumnName").Value, conditionFormatType, conditionFormatParams)); } //We need to loop through the columns in the order of the display order, starting at zero; otherwise the columns will fall out of order as the loop progresses. foreach (KeyValuePair <int, int> kvp in hash) { columnsToAdd[kvp.Value].DisplayIndex = kvp.Key; } activeColumns = enumCols; }