|
//------------------------------------------------------------------------------
// <copyright file="DataGridViewMethods.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Windows.Forms
{
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.ComponentModel;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Security;
using System.Security.Permissions;
using System.Collections;
using System.Windows.Forms.Design;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms.ComponentModel;
using System.Globalization;
using System.Diagnostics;
using System.Windows.Forms.VisualStyles;
using System.Windows.Forms.Layout;
using Microsoft.Win32;
using System.Collections.Specialized;
using System.Windows.Forms.Internal;
using System.Runtime.Versioning;
using Runtime.CompilerServices;
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView"]/*' />
public partial class DataGridView
{
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AccessibilityNotifyCurrentCellChanged"]/*' />
protected virtual void AccessibilityNotifyCurrentCellChanged(Point cellAddress)
{
if (cellAddress.X < 0 || cellAddress.X >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("cellAddress");
}
if (cellAddress.Y < 0 || cellAddress.Y >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("cellAddress");
}
int visibleRowIndex = this.Rows.GetRowCount(DataGridViewElementStates.Visible, 0, cellAddress.Y);
int visibleColumnIndex = this.Columns.ColumnIndexToActualDisplayIndex(cellAddress.X, DataGridViewElementStates.Visible);
int topHeaderRowIncrement = this.ColumnHeadersVisible ? 1 : 0;
int rowHeaderIncrement = this.RowHeadersVisible ? 1 : 0;
int objectID = visibleRowIndex + topHeaderRowIncrement // + 1 because the top header row acc obj is at index 0
+ 1; // + 1 because objectID's need to be positive and non-zero
int childID = visibleColumnIndex + rowHeaderIncrement; // + 1 because the column header cell is at index 0 in top header row acc obj
// same thing for the row header cell in the data grid view row acc obj
if (this.ContainsFocus)
{
this.AccessibilityNotifyClients(AccessibleEvents.Focus, objectID, childID);
if (AccessibilityImprovements.Level3)
{
CurrentCell?.AccessibilityObject.SetFocus();
}
}
this.AccessibilityNotifyClients(AccessibleEvents.Selection, objectID, childID);
}
internal void ActivateToolTip(bool activate, string toolTipText, int columnIndex, int rowIndex)
{
this.toolTipCaption = toolTipText;
this.ptToolTipCell = new Point(columnIndex, rowIndex);
this.toolTipControl.Activate(activate);
}
internal void AddNewRow(bool createdByEditing)
{
Debug.Assert(this.Columns.Count > 0);
Debug.Assert(this.newRowIndex == -1);
this.Rows.AddInternal(true /*newRow*/, null /*values*/);
this.newRowIndex = this.Rows.Count - 1;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowCreatedByEditing] = createdByEditing;
if (createdByEditing)
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs(this.Rows[this.newRowIndex]);
OnUserAddedRow(dgvre);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AdjustColumnHeaderBorderStyle"]/*' />
[
EditorBrowsable(EditorBrowsableState.Advanced)
]
public virtual DataGridViewAdvancedBorderStyle AdjustColumnHeaderBorderStyle(DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput,
DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder,
bool isFirstDisplayedColumn,
bool isLastVisibleColumn)
{
if (this.ApplyVisualStylesToHeaderCells)
{
switch (dataGridViewAdvancedBorderStyleInput.All)
{
case DataGridViewAdvancedCellBorderStyle.OutsetPartial:
case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
if (this.RightToLeftInternal)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.None : DataGridViewAdvancedCellBorderStyle.Outset;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
}
}
else
{
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.None : DataGridViewAdvancedCellBorderStyle.OutsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
}
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
}
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = DataGridViewAdvancedCellBorderStyle.OutsetDouble;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Outset;
return dataGridViewAdvancedBorderStylePlaceholder;
case DataGridViewAdvancedCellBorderStyle.InsetDouble:
if (this.RightToLeftInternal)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.None : DataGridViewAdvancedCellBorderStyle.Inset;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
}
}
else
{
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.None : DataGridViewAdvancedCellBorderStyle.InsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
}
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
}
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = DataGridViewAdvancedCellBorderStyle.InsetDouble;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Inset;
return dataGridViewAdvancedBorderStylePlaceholder;
case DataGridViewAdvancedCellBorderStyle.Single:
case DataGridViewAdvancedCellBorderStyle.Outset:
case DataGridViewAdvancedCellBorderStyle.Inset:
if (!isFirstDisplayedColumn || this.RowHeadersVisible)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = dataGridViewAdvancedBorderStyleInput.All;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = dataGridViewAdvancedBorderStyleInput.All;
return dataGridViewAdvancedBorderStylePlaceholder;
}
else
{
// isFirstDisplayedColumn == true && this.RowHeadersVisible == false
if (this.RightToLeftInternal)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = dataGridViewAdvancedBorderStyleInput.All;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = dataGridViewAdvancedBorderStyleInput.All;
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
}
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = dataGridViewAdvancedBorderStyleInput.All;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = dataGridViewAdvancedBorderStyleInput.All;
return dataGridViewAdvancedBorderStylePlaceholder;
}
}
}
else
{
switch (dataGridViewAdvancedBorderStyleInput.All)
{
case DataGridViewAdvancedCellBorderStyle.OutsetPartial:
if (this.RightToLeftInternal)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = isLastVisibleColumn ? DataGridViewAdvancedCellBorderStyle.Outset : DataGridViewAdvancedCellBorderStyle.OutsetPartial;
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.Outset : DataGridViewAdvancedCellBorderStyle.OutsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.OutsetPartial;
}
}
else
{
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.Outset : DataGridViewAdvancedCellBorderStyle.OutsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.OutsetPartial;
}
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = isLastVisibleColumn ? DataGridViewAdvancedCellBorderStyle.Outset : DataGridViewAdvancedCellBorderStyle.OutsetPartial;
}
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = DataGridViewAdvancedCellBorderStyle.OutsetDouble;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Outset;
return dataGridViewAdvancedBorderStylePlaceholder;
case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
if (this.RightToLeftInternal)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.Outset;
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.Outset : DataGridViewAdvancedCellBorderStyle.OutsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.Outset;
}
}
else
{
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.Outset : DataGridViewAdvancedCellBorderStyle.OutsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.Outset;
}
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.Outset;
}
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = DataGridViewAdvancedCellBorderStyle.OutsetDouble;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Outset;
return dataGridViewAdvancedBorderStylePlaceholder;
case DataGridViewAdvancedCellBorderStyle.InsetDouble:
if (this.RightToLeftInternal)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.Inset;
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.Inset : DataGridViewAdvancedCellBorderStyle.InsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.Inset;
}
}
else
{
if (isFirstDisplayedColumn)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = this.RowHeadersVisible ? DataGridViewAdvancedCellBorderStyle.Inset : DataGridViewAdvancedCellBorderStyle.InsetDouble;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.Inset;
}
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.Inset;
}
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = DataGridViewAdvancedCellBorderStyle.InsetDouble;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Inset;
return dataGridViewAdvancedBorderStylePlaceholder;
case DataGridViewAdvancedCellBorderStyle.Single:
if (!isFirstDisplayedColumn || this.RowHeadersVisible)
{
if (this.RightToLeftInternal)
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.Single;
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
}
else
{
dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.Single;
}
dataGridViewAdvancedBorderStylePlaceholder.TopInternal = DataGridViewAdvancedCellBorderStyle.Single;
dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Single;
return dataGridViewAdvancedBorderStylePlaceholder;
}
break;
}
}
return dataGridViewAdvancedBorderStyleInput;
}
private bool AdjustExpandingColumn(DataGridViewColumn dataGridViewColumn, int rowIndex)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(rowIndex > -1);
Debug.Assert(rowIndex < this.Rows.Count);
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return false;
}
bool ret = false; // No autosizing occurs by default.
try
{
this.noAutoSizeCount++;
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
int preferredThickness = dataGridViewRow.Cells[dataGridViewColumn.Index].GetPreferredWidth(rowIndex, dataGridViewRow.GetHeight(rowIndex));
if (preferredThickness > DataGridViewBand.maxBandThickness)
{
preferredThickness = DataGridViewBand.maxBandThickness;
}
if (dataGridViewColumn.Width < preferredThickness)
{
// Column needs to be expanded
dataGridViewColumn.ThicknessInternal = preferredThickness;
ret = true;
}
}
finally
{
Debug.Assert(this.noAutoSizeCount > 0);
this.noAutoSizeCount--;
}
return ret;
}
private bool AdjustExpandingColumns(DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFilter, int rowIndex)
{
Debug.Assert(autoSizeColumnCriteriaFilter != DataGridViewAutoSizeColumnCriteriaInternal.None);
Debug.Assert((autoSizeColumnCriteriaFilter & DataGridViewAutoSizeColumnCriteriaInternal.Fill) == 0);
bool ret = false; // No column autosizes by default
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
while (dataGridViewColumn != null)
{
DataGridViewAutoSizeColumnCriteriaInternal inheritedAutoSizeColumnCriteria = (DataGridViewAutoSizeColumnCriteriaInternal)dataGridViewColumn.InheritedAutoSizeMode;
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFiltered = (inheritedAutoSizeColumnCriteria & autoSizeColumnCriteriaFilter);
if (autoSizeColumnCriteriaFiltered != 0)
{
ret |= AdjustExpandingColumn(dataGridViewColumn, rowIndex);
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
return ret;
}
private int AdjustExpandingRow(int rowIndex, int columnIndex, bool fixedWidth)
{
Debug.Assert(columnIndex >= -1 && columnIndex < this.Columns.Count);
Debug.Assert(rowIndex >= 0 && rowIndex < this.Rows.Count);
Debug.Assert(this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedHeaders ||
this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders ||
this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedCells);
// Use of WindowsFormsUtils.CreateMeasurementGraphics() avoid use of this.Handle
// IntPtr handle = this.Handle; // Force creation of control's handle because for databound grids, handle creation wipes out and recreates the columns/rows.
int width = 0;
DataGridViewCell dataGridViewCell;
if (columnIndex > -1 && (((DataGridViewAutoSizeRowsModeInternal) autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
if (fixedWidth)
{
width = this.Columns[columnIndex].Thickness;
}
}
else
{
Debug.Assert(columnIndex == -1);
Debug.Assert((((DataGridViewAutoSizeRowsModeInternal) autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.Header) != 0);
dataGridViewCell = this.Rows.SharedRow(rowIndex).HeaderCell;
if (fixedWidth)
{
Debug.Assert(this.RowHeadersWidth > 0);
Debug.Assert(this.RowHeadersVisible);
width = this.RowHeadersWidth;
}
}
int preferredThickness;
if (fixedWidth)
{
preferredThickness = dataGridViewCell.GetPreferredHeight(rowIndex, width);
}
else
{
preferredThickness = dataGridViewCell.GetPreferredSize(rowIndex).Height;
}
int height, minimumHeight;
this.Rows.SharedRow(rowIndex).GetHeightInfo(rowIndex, out height, out minimumHeight);
if (preferredThickness < height)
{
preferredThickness = height;
}
Debug.Assert(preferredThickness >= minimumHeight);
if (preferredThickness > DataGridViewBand.maxBandThickness)
{
preferredThickness = DataGridViewBand.maxBandThickness;
}
if (height != preferredThickness)
{
Debug.Assert(this.autoSizeRowsMode != DataGridViewAutoSizeRowsMode.None);
this.Rows[rowIndex].Thickness = preferredThickness; // unsharing the resized row
}
return preferredThickness;
}
[SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops")] // Can't cache DataGridViewRow object because rowIndex is changing in loop.
private void AdjustExpandingRows(int columnIndex, bool fixedWidth)
{
if ((((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0 ||
((((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.Header) != 0 && this.RowHeadersVisible))
{
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return;
}
// Very expensive processing - the developer should avoid this scenario.
// Switch to batch operation
this.inBulkPaintCount++;
try
{
if ((((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllRows) != 0)
{
this.inBulkLayoutCount++;
try
{
for (int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
int width = 0;
DataGridViewCell dataGridViewCell;
if (columnIndex > -1 && (((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
if (fixedWidth)
{
width = this.Columns[columnIndex].Thickness;
}
}
else
{
//Debug.Assert(columnIndex == -1);
Debug.Assert((((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.Header) != 0);
dataGridViewCell = this.Rows.SharedRow(rowIndex).HeaderCell;
if (fixedWidth)
{
Debug.Assert(this.RowHeadersWidth > 0);
Debug.Assert(this.RowHeadersVisible);
width = this.RowHeadersWidth;
}
}
int preferredHeight;
if (fixedWidth)
{
preferredHeight = dataGridViewCell.GetPreferredHeight(rowIndex, width);
}
else
{
preferredHeight = dataGridViewCell.GetPreferredSize(rowIndex).Height;
}
if (this.Rows.SharedRow(rowIndex).Height < preferredHeight)
{
this.Rows[rowIndex].Height = preferredHeight; // unsharing the row to be resized
}
}
}
finally
{
ExitBulkLayout(false /*invalidInAdjustFillingColumns*/);
}
}
else
{
Debug.Assert((((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.DisplayedRows) != 0);
int displayHeight = this.layout.Data.Height;
int cy = 0;
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (rowIndex != -1 && cy < displayHeight)
{
cy += AdjustExpandingRow(rowIndex, columnIndex, fixedWidth);
rowIndex = this.Rows.GetNextRow(rowIndex,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
if (cy < displayHeight)
{
rowIndex = this.displayedBandsInfo.FirstDisplayedScrollingRow;
while (rowIndex != -1 && cy < displayHeight)
{
cy += AdjustExpandingRow(rowIndex, columnIndex, fixedWidth);
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
}
}
}
finally
{
ExitBulkPaint(-1, -1);
}
}
}
internal void AdjustFillingColumn(DataGridViewColumn dataGridViewColumn, int width)
{
if (this.InAdjustFillingColumns)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAlterAutoFillColumnParameter));
}
this.dataGridViewOper[DATAGRIDVIEWOPER_inAdjustFillingColumn] = true;
try
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(dataGridViewColumn.Visible);
Debug.Assert(!dataGridViewColumn.Frozen);
Debug.Assert(dataGridViewColumn.MinimumWidth <= width);
Debug.Assert(dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill);
Debug.Assert(!this.layout.dirty);
if (this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) > this.layout.Data.Width)
{
// Columns are scrolling - this means that all columns have reached their minimum width.
// Do not affect their width or fill weight
Debug.Assert(dataGridViewColumn.MinimumWidth == dataGridViewColumn.Width);
return;
}
int availableWidth = this.layout.Data.Width; // Width available for auto-filled columns
// Check if the column is the first or last visible scrolling column
if (this.DesignMode ||
dataGridViewColumn == this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen) ||
dataGridViewColumn == this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen))
{
// Changing the width is equivalent to adjusting the FillWeight when:
// - the column is not scrolling and is the first non-frozen visible column
// - the column is not scrolling and is the last non-frozen visible column
float weightSum = 0; // Weights of all auto filled visible columns.
int widthSum = 0; // Sum of widths of visible auto filled columns.
int imposedWidthSum = 0; // Minimum width required for all other columns.
bool otherFillingColumnExists = false;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible)
{
if (dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
Debug.Assert(!dataGridViewColumnTmp.Frozen);
widthSum += dataGridViewColumnTmp.Width;
if (dataGridViewColumnTmp.Index != dataGridViewColumn.Index)
{
imposedWidthSum += dataGridViewColumnTmp.MinimumWidth;
otherFillingColumnExists = true;
}
weightSum += dataGridViewColumnTmp.FillWeight;
}
else
{
imposedWidthSum += dataGridViewColumnTmp.Width;
availableWidth -= dataGridViewColumnTmp.Width;
}
}
}
if (!otherFillingColumnExists)
{
// The resized column is the only one that is filling. This is a no-op operation.
// Neither the width nor the fill weight can change
return;
}
int maximumPossibleWidth = this.layout.Data.Width - imposedWidthSum;
if (width > maximumPossibleWidth)
{
width = maximumPossibleWidth;
}
// Determine fill weight equivalent to 'width'
float oldWeight = dataGridViewColumn.FillWeight;
float newWeight = (float)(width * weightSum) / (float)widthSum;
bool desiredWidthTooSmall = false;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Index != dataGridViewColumn.Index &&
dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
dataGridViewColumnTmp.FillWeightInternal = (weightSum - newWeight) * dataGridViewColumnTmp.FillWeight / (weightSum - oldWeight);
if (dataGridViewColumnTmp.FillWeight < (dataGridViewColumnTmp.MinimumWidth * weightSum) / (float)widthSum)
{
desiredWidthTooSmall = true;
dataGridViewColumnTmp.DesiredFillWidth = -1;
}
else
{
dataGridViewColumnTmp.DesiredFillWidth = 0;
}
}
}
dataGridViewColumn.FillWeightInternal = newWeight;
if (desiredWidthTooSmall)
{
// At least one column hits its minimum width
// Adjust UsedFillWeight values are adjusted FillWeight values
float usedWeightSumNoneMinimal = weightSum;
float weightSumNoneMinimal = weightSum;
float usedFillWeights = 0F;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
if (dataGridViewColumnTmp.Index == dataGridViewColumn.Index)
{
dataGridViewColumnTmp.UsedFillWeight = dataGridViewColumnTmp.FillWeight;
usedWeightSumNoneMinimal -= dataGridViewColumnTmp.UsedFillWeight;
weightSumNoneMinimal -= dataGridViewColumnTmp.FillWeight;
usedFillWeights += dataGridViewColumnTmp.UsedFillWeight;
}
else if (dataGridViewColumnTmp.DesiredFillWidth == -1)
{
dataGridViewColumnTmp.UsedFillWeight = weightSum * dataGridViewColumnTmp.MinimumWidth / widthSum;
usedWeightSumNoneMinimal -= dataGridViewColumnTmp.UsedFillWeight;
weightSumNoneMinimal -= dataGridViewColumnTmp.FillWeight;
usedFillWeights += dataGridViewColumnTmp.UsedFillWeight;
}
}
}
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Index != dataGridViewColumn.Index &&
dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill &&
dataGridViewColumnTmp.DesiredFillWidth != -1)
{
dataGridViewColumnTmp.UsedFillWeight = Math.Max(dataGridViewColumnTmp.FillWeight * usedWeightSumNoneMinimal / weightSumNoneMinimal,
weightSum * dataGridViewColumnTmp.MinimumWidth / widthSum);
usedFillWeights += dataGridViewColumnTmp.UsedFillWeight;
}
}
dataGridViewColumn.UsedFillWeight += weightSum - usedFillWeights;
}
else
{
// No column hits its minimum width
// Each UsedFillWeight simply equals the FillWeight
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
dataGridViewColumnTmp.UsedFillWeight = dataGridViewColumnTmp.FillWeight;
}
}
}
#if DEBUG
float weightSumDbg = 0F;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
weightSumDbg += dataGridViewColumnTmp.UsedFillWeight;
}
}
Debug.Assert(Math.Abs(weightSum - weightSumDbg) < 1.0F);
#endif
}
else
{
// This column is not the first nor the last visible non-frozen column
// Changing its width only affects the width and weight of the columns displayed after it
// First figure out the maximum possible width
int imposedWidthSum = 0; // Minimum width required for all other columns
float weightSum = 0; // Weights of all auto filled visible columns.
float oldWeightSum = 0F; // Fill weights of the columns displayed after this resized column
bool otherFillingColumnExists = false;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible)
{
if (dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
Debug.Assert(!dataGridViewColumnTmp.Frozen);
if (dataGridViewColumnTmp.Index != dataGridViewColumn.Index)
{
if (this.Columns.DisplayInOrder(dataGridViewColumn.Index, dataGridViewColumnTmp.Index))
{
imposedWidthSum += dataGridViewColumnTmp.MinimumWidth; // Column is allowed to shrink down to its minimum
oldWeightSum += dataGridViewColumnTmp.FillWeight;
}
else
{
// Column is displayed before 'dataGridViewColumn', it is not allowed to shrink at all
imposedWidthSum += dataGridViewColumnTmp.Width;
}
otherFillingColumnExists = true;
}
weightSum += dataGridViewColumnTmp.FillWeight;
}
else
{
imposedWidthSum += dataGridViewColumnTmp.Width;
availableWidth -= dataGridViewColumnTmp.Width;
}
}
}
if (!otherFillingColumnExists)
{
// The resized column is the only one that is filling. This is a no-op operation.
// Neither the width nor the fill weight can change
return;
}
int maximumPossibleWidth = this.layout.Data.Width - imposedWidthSum;
if (width > maximumPossibleWidth)
{
width = maximumPossibleWidth;
}
// Then figure out the target fill weights
float oldWeight = dataGridViewColumn.FillWeight;
float newWeight = weightSum * width / availableWidth;
float newWeightSum = oldWeightSum + oldWeight - newWeight;
Debug.Assert(newWeightSum > 0);
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Index != dataGridViewColumn.Index &&
dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill &&
this.Columns.DisplayInOrder(dataGridViewColumn.Index, dataGridViewColumnTmp.Index))
{
dataGridViewColumnTmp.FillWeightInternal = dataGridViewColumnTmp.FillWeight * newWeightSum / oldWeightSum;
}
}
dataGridViewColumn.FillWeightInternal = newWeight;
bool desiredWidthTooSmall = false;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
if (dataGridViewColumnTmp.FillWeight < (dataGridViewColumnTmp.MinimumWidth * weightSum) / (float)availableWidth)
{
desiredWidthTooSmall = true;
dataGridViewColumnTmp.DesiredFillWidth = -1;
}
else
{
dataGridViewColumnTmp.DesiredFillWidth = 0;
}
}
}
if (desiredWidthTooSmall)
{
// At least one column hits its minimum width
// Adjust UsedFillWeight values are adjusted FillWeight values
float usedWeightSumNoneMinimal = weightSum;
float weightSumNoneMinimal = weightSum;
float usedFillWeights = 0F;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
if (dataGridViewColumnTmp.Index == dataGridViewColumn.Index ||
this.Columns.DisplayInOrder(dataGridViewColumnTmp.Index, dataGridViewColumn.Index))
{
if (dataGridViewColumnTmp.Index == dataGridViewColumn.Index)
{
dataGridViewColumnTmp.UsedFillWeight = dataGridViewColumnTmp.FillWeight;
}
else
{
dataGridViewColumnTmp.UsedFillWeight = weightSum * dataGridViewColumnTmp.Width / availableWidth;
}
usedWeightSumNoneMinimal -= dataGridViewColumnTmp.UsedFillWeight;
weightSumNoneMinimal -= dataGridViewColumnTmp.FillWeight;
usedFillWeights += dataGridViewColumnTmp.UsedFillWeight;
}
else if (dataGridViewColumnTmp.DesiredFillWidth == -1)
{
dataGridViewColumnTmp.UsedFillWeight = weightSum * dataGridViewColumnTmp.MinimumWidth / availableWidth;
usedWeightSumNoneMinimal -= dataGridViewColumnTmp.UsedFillWeight;
weightSumNoneMinimal -= dataGridViewColumnTmp.FillWeight;
usedFillWeights += dataGridViewColumnTmp.UsedFillWeight;
}
}
}
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (this.Columns.DisplayInOrder(dataGridViewColumn.Index, dataGridViewColumnTmp.Index) &&
dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill &&
dataGridViewColumnTmp.DesiredFillWidth != -1)
{
dataGridViewColumnTmp.UsedFillWeight = Math.Max(dataGridViewColumnTmp.FillWeight * usedWeightSumNoneMinimal / weightSumNoneMinimal,
weightSum * dataGridViewColumnTmp.MinimumWidth / availableWidth);
usedFillWeights += dataGridViewColumnTmp.UsedFillWeight;
}
}
dataGridViewColumn.UsedFillWeight += weightSum - usedFillWeights;
}
else
{
// No column hits its minimum width
// Each UsedFillWeight simply equals the FillWeight
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
dataGridViewColumnTmp.UsedFillWeight = dataGridViewColumnTmp.FillWeight;
}
}
}
#if DEBUG
float weightSumDbg = 0F;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
weightSumDbg += dataGridViewColumnTmp.UsedFillWeight;
}
}
Debug.Assert(Math.Abs(weightSum - weightSumDbg) < 1.0F);
#endif
}
// UsedFillWeight properties are up-to-date
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = false;
this.availableWidthForFillColumns = availableWidth;
// AdjustFillingColumns() will resize columns based on the UsedFillWeight values
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inAdjustFillingColumn] = false;
}
}
private bool AdjustFillingColumns()
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inAdjustFillingColumns])
{
// No need to auto fill columns while we're already doing it.
return false;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_inAdjustFillingColumns] = true;
bool columnsAdjusted = false;
try
{
// Determine free space for filling columns.
int numVisibleFillColumns = 0; // number of visible columns that are auto filled.
int imposedWidthSum = 0; // total width of columns that don't have a flexible width.
int requiredWidthSum = 0; // total of the minimum widths of the visible auto filled columns.
float weightSum = 0F; // total of the weights of the visible auto filled columns.
ArrayList autoFillColumns = null;
foreach (DataGridViewColumn dataGridViewColumn in this.Columns)
{
if (dataGridViewColumn.Visible)
{
if (dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
Debug.Assert(!dataGridViewColumn.Frozen);
numVisibleFillColumns++;
requiredWidthSum += dataGridViewColumn.DesiredMinimumWidth > 0 ? dataGridViewColumn.DesiredMinimumWidth : dataGridViewColumn.MinimumWidth;
weightSum += dataGridViewColumn.FillWeight;
if (autoFillColumns == null)
{
autoFillColumns = new ArrayList(this.Columns.Count);
}
autoFillColumns.Add(dataGridViewColumn);
}
else
{
imposedWidthSum += dataGridViewColumn.Width;
}
}
}
if (numVisibleFillColumns > 0)
{
// Assuming no vertical scrollbar has been accounted for yet
Debug.Assert(this.layout.Data.Width == this.layout.Inside.Width - this.layout.RowHeaders.Width - (this.SingleVerticalBorderAdded ? 1 : 0));
int availableWidth = this.layout.Data.Width - imposedWidthSum;
if ((this.scrollBars == ScrollBars.Both || this.scrollBars == ScrollBars.Vertical) /*&&
(availableWidth > requiredWidthSum || this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty])*/)
{
int totalVisibleRowCount = this.Rows.GetRowCount(DataGridViewElementStates.Visible);
int totalVisibleHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible);
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
// Assuming there is no horizontal scrollbar, is a vertical scrollbar required?
ComputeVisibleRows(); // Make sure this.displayedBandsInfo.FirstDisplayedScrollingRow and other row count info variables have been set
if (this.displayedBandsInfo.NumTotallyDisplayedFrozenRows == this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen) &&
this.displayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount - this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen) &&
(totalVisibleHeight - totalVisibleFrozenHeight != ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight)) &&
this.layout.Data.Height > totalVisibleFrozenHeight &&
SystemInformation.VerticalScrollBarWidth <= this.layout.Data.Width)
{
// Vertical scrollbar is required, even when there is not horizontal one.
availableWidth -= SystemInformation.VerticalScrollBarWidth;
}
}
int columnEntry;
if (availableWidth <= requiredWidthSum)
{
// All auto filled columns need to take their minimum width. If (availableWidth < requiredWidthSum) a horizontal scrollbar appears.
availableWidth = 0;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
int minimumWidth = dataGridViewColumn.DesiredMinimumWidth > 0 ? dataGridViewColumn.DesiredMinimumWidth : dataGridViewColumn.MinimumWidth;
if (dataGridViewColumn.Thickness != minimumWidth)
{
columnsAdjusted = true;
dataGridViewColumn.ThicknessInternal = minimumWidth;
}
availableWidth += dataGridViewColumn.Thickness;
}
//if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty])
{
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
// Make sure the UsedFillWeight correspond to the actual column width
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
dataGridViewColumn.UsedFillWeight = dataGridViewColumn.Width * weightSum / availableWidth;
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = false;
this.availableWidthForFillColumns = availableWidth;
}
return columnsAdjusted;
}
// Auto filling columns can share some real estate.
int usedWidth = 0;
// Update the UsedFillWeight value if dirty
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty])
{
// Assign desired widths
Debug.Assert(weightSum > 0);
bool desiredWidthTooSmall = false;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
if (columnEntry == autoFillColumns.Count - 1)
{
dataGridViewColumn.DesiredFillWidth = availableWidth - usedWidth;
}
else
{
float desiredFillWidth = (dataGridViewColumn.FillWeight / weightSum) * availableWidth;
dataGridViewColumn.DesiredFillWidth = (int)Math.Round(desiredFillWidth, MidpointRounding.AwayFromZero);
usedWidth += dataGridViewColumn.DesiredFillWidth;
}
int minimumWidth = dataGridViewColumn.DesiredMinimumWidth > 0 ? dataGridViewColumn.DesiredMinimumWidth : dataGridViewColumn.MinimumWidth;
if (dataGridViewColumn.DesiredFillWidth < minimumWidth)
{
desiredWidthTooSmall = true;
dataGridViewColumn.DesiredFillWidth = -1;
}
}
if (desiredWidthTooSmall)
{
// At least one column hits its minimum width
// Adjust UsedFillWeight values are adjusted FillWeight values
float usedWeightSumNoneMinimal = weightSum;
float weightSumNoneMinimal = weightSum;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
if (dataGridViewColumn.DesiredFillWidth == -1)
{
int minimumWidth = dataGridViewColumn.DesiredMinimumWidth > 0 ? dataGridViewColumn.DesiredMinimumWidth : dataGridViewColumn.MinimumWidth;
dataGridViewColumn.UsedFillWeight = weightSum * minimumWidth / availableWidth;
usedWeightSumNoneMinimal -= dataGridViewColumn.UsedFillWeight;
weightSumNoneMinimal -= dataGridViewColumn.FillWeight;
}
}
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
if (dataGridViewColumn.DesiredFillWidth != -1)
{
dataGridViewColumn.UsedFillWeight = dataGridViewColumn.FillWeight * usedWeightSumNoneMinimal / weightSumNoneMinimal;
}
}
}
else
{
// No column hits its minimum width
// Each UsedFillWeight simply equals the FillWeight
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
dataGridViewColumn.UsedFillWeight = dataGridViewColumn.FillWeight;
}
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = false;
this.availableWidthForFillColumns = availableWidth;
}
else if (availableWidth != this.availableWidthForFillColumns)
{
// The available width for auto-filled columns has changed - UsedFillWeight values need to be adjusted.
if (availableWidth > this.availableWidthForFillColumns)
{
// Available width increased
int widthGain = availableWidth - this.availableWidthForFillColumns;
// Allocate additional width according to UsedFillWeight and FillWeight values
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
dataGridViewColumn.DesiredFillWidth = dataGridViewColumn.Width;
}
float[] floatDesiredWidths = new float[autoFillColumns.Count];
for (int gain = 0; gain < widthGain; gain++)
{
float fillWeightRatioSum = 0F;
bool minimumColumnExists = false;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
fillWeightRatioSum += dataGridViewColumn.FillWeight / dataGridViewColumn.UsedFillWeight;
if (dataGridViewColumn.DesiredFillWidth <= dataGridViewColumn.MinimumWidth)
{
minimumColumnExists = true;
}
}
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
if (gain == 0)
{
floatDesiredWidths[columnEntry] = this.availableWidthForFillColumns * dataGridViewColumn.UsedFillWeight / weightSum;
}
if (minimumColumnExists)
{
floatDesiredWidths[columnEntry] += dataGridViewColumn.FillWeight / dataGridViewColumn.UsedFillWeight / fillWeightRatioSum;
}
else
{
floatDesiredWidths[columnEntry] += dataGridViewColumn.FillWeight / weightSum;
}
}
}
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
dataGridViewColumn.UsedFillWeight = weightSum / availableWidth * floatDesiredWidths[columnEntry];
}
}
else
{
// availableWidth < this.availableWidthForFillColumns - Available width decreased
int totalWidthLoss = this.availableWidthForFillColumns - availableWidth;
int cumulatedWidthLoss = 0;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
dataGridViewColumn.DesiredFillWidth = dataGridViewColumn.Width;
}
// the width loss is accounted for in steps of 10% (see VSWhidbey 568343)
do
{
int stepDownAvailableWidthForFillColumns = this.availableWidthForFillColumns - cumulatedWidthLoss;
int widthLoss = Math.Min(stepDownAvailableWidthForFillColumns - availableWidth, Math.Max(1, (int)(stepDownAvailableWidthForFillColumns * 0.1F)));
cumulatedWidthLoss += widthLoss;
bool changeDone;
do
{
changeDone = false;
// Determine which column deserves to shrink the most
float biggestWeightDeficiency = 0F, fillWeightRatioSum = 0F, fillWeightRatio;
DataGridViewColumn mostDeservingDataGridViewColumn = null;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
if (dataGridViewColumn.DesiredFillWidth > dataGridViewColumn.MinimumWidth)
{
fillWeightRatio = dataGridViewColumn.UsedFillWeight / dataGridViewColumn.FillWeight;
fillWeightRatioSum += fillWeightRatio;
if (fillWeightRatio > biggestWeightDeficiency)
{
mostDeservingDataGridViewColumn = dataGridViewColumn;
biggestWeightDeficiency = fillWeightRatio;
}
}
}
if (mostDeservingDataGridViewColumn != null)
{
float floatDesiredWidth = (stepDownAvailableWidthForFillColumns * mostDeservingDataGridViewColumn.UsedFillWeight / weightSum) - widthLoss * mostDeservingDataGridViewColumn.UsedFillWeight / mostDeservingDataGridViewColumn.FillWeight / fillWeightRatioSum;
if (floatDesiredWidth < (float)mostDeservingDataGridViewColumn.MinimumWidth)
{
floatDesiredWidth = (int)mostDeservingDataGridViewColumn.MinimumWidth;
}
int oldDesiredWidth = mostDeservingDataGridViewColumn.DesiredFillWidth;
mostDeservingDataGridViewColumn.DesiredFillWidth = Math.Min(oldDesiredWidth, (int)Math.Round(floatDesiredWidth, MidpointRounding.AwayFromZero));
changeDone = (oldDesiredWidth != mostDeservingDataGridViewColumn.DesiredFillWidth);
if (!changeDone && widthLoss == 1 && oldDesiredWidth > mostDeservingDataGridViewColumn.MinimumWidth)
{
mostDeservingDataGridViewColumn.DesiredFillWidth--;
changeDone = true;
}
Debug.Assert(oldDesiredWidth >= mostDeservingDataGridViewColumn.DesiredFillWidth);
widthLoss -= oldDesiredWidth - mostDeservingDataGridViewColumn.DesiredFillWidth;
if (changeDone)
{
stepDownAvailableWidthForFillColumns -= oldDesiredWidth - mostDeservingDataGridViewColumn.DesiredFillWidth;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
dataGridViewColumn.UsedFillWeight = weightSum / stepDownAvailableWidthForFillColumns * dataGridViewColumn.DesiredFillWidth;
}
}
Debug.Assert(widthLoss >= 0);
}
}
while (changeDone && widthLoss > 0);
}
while (cumulatedWidthLoss < totalWidthLoss);
}
this.availableWidthForFillColumns = availableWidth;
}
#if DEBUG
float weightSumDbg = 0F;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
weightSumDbg += dataGridViewColumn.UsedFillWeight;
}
Debug.Assert(Math.Abs(weightSum - weightSumDbg) < 1.0F);
#endif
// Finally update the columns' width according the UsedFillWeight values.
try
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_allowHorizontalScrollbar] = false;
usedWidth = 0;
float carryover = 0F;
while (autoFillColumns.Count > 0)
{
DataGridViewColumn mostDeservingDataGridViewColumn = null;
if (autoFillColumns.Count == 1)
{
mostDeservingDataGridViewColumn = (DataGridViewColumn)autoFillColumns[0];
mostDeservingDataGridViewColumn.DesiredFillWidth = Math.Max(availableWidth - usedWidth, mostDeservingDataGridViewColumn.MinimumWidth);
autoFillColumns.Clear();
}
else
{
float biggestWeightDiscrepancy = 0F, weightDiscrepancy;
for (columnEntry = 0; columnEntry < autoFillColumns.Count; columnEntry++)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)autoFillColumns[columnEntry];
weightDiscrepancy = Math.Abs(dataGridViewColumn.UsedFillWeight - dataGridViewColumn.FillWeight) / dataGridViewColumn.FillWeight;
if (weightDiscrepancy > biggestWeightDiscrepancy || mostDeservingDataGridViewColumn == null)
{
mostDeservingDataGridViewColumn = dataGridViewColumn;
biggestWeightDiscrepancy = weightDiscrepancy;
}
}
float floatDesiredWidth = (mostDeservingDataGridViewColumn.UsedFillWeight * availableWidth / weightSum) + carryover;
mostDeservingDataGridViewColumn.DesiredFillWidth = Math.Max(mostDeservingDataGridViewColumn.MinimumWidth, (int)Math.Round(floatDesiredWidth, MidpointRounding.AwayFromZero));
carryover = floatDesiredWidth - mostDeservingDataGridViewColumn.DesiredFillWidth;
usedWidth += mostDeservingDataGridViewColumn.DesiredFillWidth;
autoFillColumns.Remove(mostDeservingDataGridViewColumn);
}
if (mostDeservingDataGridViewColumn.DesiredFillWidth != mostDeservingDataGridViewColumn.Thickness)
{
columnsAdjusted = true;
mostDeservingDataGridViewColumn.ThicknessInternal = mostDeservingDataGridViewColumn.DesiredFillWidth;
}
}
}
finally
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_allowHorizontalScrollbar] = true;
}
}
#if DEBUG
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty])
{
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
Debug.Assert(Math.Abs(dataGridViewColumnTmp.UsedFillWeight * this.availableWidthForFillColumns - weightSum * dataGridViewColumnTmp.Width) / weightSum / dataGridViewColumnTmp.Width <= 1.25F / dataGridViewColumnTmp.Width);
}
}
}
bool nonMinColumnExists = false;
int widthSum = 0;
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.Visible &&
dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
widthSum += dataGridViewColumnTmp.Width;
if (dataGridViewColumnTmp.Width > dataGridViewColumnTmp.MinimumWidth)
{
nonMinColumnExists = true;
}
}
}
if (nonMinColumnExists)
{
Debug.Assert(widthSum == this.availableWidthForFillColumns);
}
#endif
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inAdjustFillingColumns] = false;
}
return columnsAdjusted;
}
private void AdjustShrinkingRows(DataGridViewAutoSizeRowsMode autoSizeRowsMode, bool fixedWidth, bool internalAutosizing)
{
if ((((DataGridViewAutoSizeRowsModeInternal) autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0 ||
((((DataGridViewAutoSizeRowsModeInternal) autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.Header) != 0 && this.RowHeadersVisible))
{
// Switch to batch operation
this.inBulkPaintCount++;
try
{
if ((((DataGridViewAutoSizeRowsModeInternal) autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllRows) != 0)
{
// Very expensive processing - the developer should avoid this scenario.
this.inBulkLayoutCount++;
try
{
for (int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(autoSizeRowsMode), fixedWidth, internalAutosizing);
}
}
finally
{
ExitBulkLayout(false /*invalidInAdjustFillingColumns*/);
}
}
else
{
Debug.Assert((((DataGridViewAutoSizeRowsModeInternal) autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.DisplayedRows) != 0);
int displayHeight = this.layout.Data.Height;
int cy = 0;
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (rowIndex != -1 && cy < displayHeight)
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(autoSizeRowsMode), fixedWidth, internalAutosizing);
cy += this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
rowIndex = this.Rows.GetNextRow(rowIndex,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
if (cy < displayHeight)
{
int cyFrozen = cy;
int oldFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
rowIndex = oldFirstVisibleScrollingRow;
while (rowIndex != -1 &&
cy < displayHeight &&
oldFirstVisibleScrollingRow == this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(autoSizeRowsMode), fixedWidth, internalAutosizing);
cy += this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
do
{
oldFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
if (cy < displayHeight)
{
int rowAboveFirstVisibleScrollingRow = this.Rows.GetPreviousRow(this.displayedBandsInfo.FirstDisplayedScrollingRow, DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
if (rowAboveFirstVisibleScrollingRow != -1)
{
AutoResizeRowInternal(rowAboveFirstVisibleScrollingRow, MapAutoSizeRowsModeToRowMode(autoSizeRowsMode), fixedWidth, internalAutosizing);
}
}
cy = cyFrozen;
rowIndex = this.displayedBandsInfo.FirstDisplayedScrollingRow;
while (rowIndex != -1 && cy < displayHeight)
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(autoSizeRowsMode), fixedWidth, internalAutosizing);
cy += this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
}
while (oldFirstVisibleScrollingRow != this.displayedBandsInfo.FirstDisplayedScrollingRow);
}
}
}
finally
{
ExitBulkPaint(-1, -1);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AreAllCellsSelected"]/*' />
// Does not seem to be a valid fxcop violation report. Contacting fxcop team to double-check.
[SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops")]
public bool AreAllCellsSelected(bool includeInvisibleCells)
{
if (this.Columns.Count == 0 && this.Rows.Count == 0)
{
return true;
}
if (!includeInvisibleCells &&
(this.Rows.GetFirstRow(DataGridViewElementStates.Visible) == -1 ||
this.Columns.GetFirstColumn(DataGridViewElementStates.Visible) == null))
{
return true;
}
DataGridViewRow dataGridViewRow = null;
bool allCellsSelected;
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
allCellsSelected = this.individualSelectedCells.Count == this.Columns.Count * this.Rows.Count;
if (allCellsSelected || includeInvisibleCells)
{
return allCellsSelected;
}
else
{
for (int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
dataGridViewRow = this.Rows[rowIndex]; // unshares this row
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
while (dataGridViewColumn != null)
{
if (!dataGridViewRow.Cells[dataGridViewColumn.Index].Selected)
{
return false;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
}
return true;
}
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
allCellsSelected = this.selectedBandIndexes.Count * this.Rows.Count + this.individualSelectedCells.Count == this.Columns.Count * this.Rows.Count;
if (allCellsSelected || includeInvisibleCells)
{
return allCellsSelected;
}
else
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
while (dataGridViewColumn != null)
{
if (!this.selectedBandIndexes.Contains(dataGridViewColumn.Index))
{
for (int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
dataGridViewRow = this.Rows[rowIndex]; // unshares this row
if (!dataGridViewRow.Cells[dataGridViewColumn.Index].Selected)
{
return false;
}
}
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
return true;
}
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
allCellsSelected = this.selectedBandIndexes.Count * this.Columns.Count + this.individualSelectedCells.Count == this.Columns.Count * this.Rows.Count;
if (allCellsSelected || includeInvisibleCells)
{
return allCellsSelected;
}
else
{
for (int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
Debug.Assert(this.selectedBandIndexes.Contains(rowIndex) ==
((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Selected) != 0));
if ((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Selected) == 0)
{
dataGridViewRow = this.Rows[rowIndex]; // unshares this row
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
while (dataGridViewColumn != null)
{
if (!dataGridViewRow.Cells[dataGridViewColumn.Index].Selected)
{
return false;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
}
}
return true;
}
}
}
Debug.Fail("DataGridView.AreAllCellsSelected - Shouldn't reach this code");
return false;
}
/// <devdoc>
/// <para>Assigns a new parent control to the DataGridView.</para>
/// </devdoc>
internal override void AssignParent(Control value)
{
if (this.toolTipControl.Activated)
{
this.toolTipControl.Activate(false /*activate*/);
}
base.AssignParent(value);
}
private void AutoGenerateDataBoundColumns(DataGridViewColumn[] boundColumns)
{
DataGridViewColumnCollection dataGridViewCols = this.Columns;
DataGridViewColumn[] clonedColumns = new DataGridViewColumn[dataGridViewCols.Count];
int clonedColumnsCount = 0;
int i;
// 1. Clone all the columns which are currently bound and will also be bound under the new DataSource/DataMember combination.
// 2. Delete all the currently bound columns.
// 3. Sort the cloned columns in order of their DisplayIndex.
// 4. Add the new data bound columns. Here are the rules:
// a. if the cloned collection contains (possible multiple) columns with DataProperyHame == current data field,
// add the first cloned column that maps to the data field.
// b. other wise add the new bound column.
// 5. Add the remaining cloned columns in the order of their DisplayIndex.
// 1. Clone all the currently bound columns.
//
// We can't do 1. and 2. in the same loop because we need to save the DisplayIndex.
for (i = 0; i < dataGridViewCols.Count; i++)
{
if (this.DataSource != null &&
!String.IsNullOrEmpty(dataGridViewCols[i].DataPropertyName) &&
!dataGridViewCols[i].IsDataBound)
{
MapDataGridViewColumnToDataBoundField(dataGridViewCols[i]);
}
if (dataGridViewCols[i].IsDataBound)
{
// We only clone columns which are data bound w/ the new DataSource/DataMember combination.
if (this.dataConnection != null && this.dataConnection.BoundColumnIndex(dataGridViewCols[i].DataPropertyName) != -1)
{
clonedColumns[clonedColumnsCount] = (DataGridViewColumn) dataGridViewCols[i].Clone();
clonedColumns[clonedColumnsCount].DisplayIndex = dataGridViewCols[i].DisplayIndex;
clonedColumnsCount ++;
}
}
}
i = 0;
// 2. Delete all the currently bound columns.
while (i < dataGridViewCols.Count)
{
if (dataGridViewCols[i].IsDataBound)
{
dataGridViewCols.RemoveAtInternal(i, true /*force*/);
}
else
{
i++;
}
}
// 3. Sort the cloned columns in the order of their DisplayIndex.
// Sort the cloned columns array by the display index.
// We need to copy the cloned columns into a possibly smaller array.
DataGridViewColumn[] finalClonedColumns;
if (clonedColumns.Length == clonedColumnsCount)
{
finalClonedColumns = clonedColumns;
}
else
{
finalClonedColumns = new DataGridViewColumn[clonedColumnsCount];
Array.Copy(clonedColumns, finalClonedColumns, clonedColumnsCount);
}
// Sort the array.
Array.Sort(finalClonedColumns, System.Windows.Forms.DataGridViewColumnCollection.ColumnCollectionOrderComparer);
// 4. Add new columns for the Fields which were not data bound previously ( ie, for fields which do not have a clone ).
if (boundColumns != null)
{
for (int j = 0; j < boundColumns.Length; j ++)
{
if (boundColumns[j] != null && boundColumns[j].IsBrowsableInternal)
{
bool addNewColumn = true;
// Go thru the list of cloned columns and see if there is another column w/ the same data property name.
int clonedColIndex = 0;
for (; clonedColIndex < clonedColumnsCount; clonedColIndex ++)
{
if (finalClonedColumns[clonedColIndex] != null &&
String.Compare(finalClonedColumns[clonedColIndex].DataPropertyName,
boundColumns[j].DataPropertyName,
true /*ignoreCase*/,
CultureInfo.InvariantCulture) == 0)
{
addNewColumn = false;
break;
}
}
if (addNewColumn)
{
dataGridViewCols.Add(boundColumns[j]);
}
else
{
// add the cloned column.
dataGridViewCols.Add(finalClonedColumns[clonedColIndex]);
MapDataGridViewColumnToDataBoundField(finalClonedColumns[clonedColIndex]);
Debug.Assert(finalClonedColumns[clonedColIndex].IsDataBound);
finalClonedColumns[clonedColIndex] = null;
}
}
}
}
#if DEBUG
else
{
// If there are no data bound columns then there are no cloned columns either.
Debug.Assert(finalClonedColumns.Length == 0);
Debug.Assert(clonedColumnsCount == 0);
}
#endif // DEBUG
// 5. Add remaining cloned columns.
if (clonedColumnsCount > 0)
{
for (int k = 0; k < finalClonedColumns.Length; k++)
{
if (finalClonedColumns[k] != null)
{
dataGridViewCols.Add(finalClonedColumns[k]);
MapDataGridViewColumnToDataBoundField(finalClonedColumns[k]);
Debug.Assert(finalClonedColumns[k].IsDataBound);
}
}
}
}
private bool AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFilter, bool fixedHeight)
{
Debug.Assert(autoSizeColumnCriteriaFilter != DataGridViewAutoSizeColumnCriteriaInternal.None);
Debug.Assert((autoSizeColumnCriteriaFilter & DataGridViewAutoSizeColumnCriteriaInternal.Fill) == 0);
bool ret = false; // No column autosizes by default
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
while (dataGridViewColumn != null)
{
DataGridViewAutoSizeColumnCriteriaInternal inheritedAutoSizeColumnCriteria = (DataGridViewAutoSizeColumnCriteriaInternal) dataGridViewColumn.InheritedAutoSizeMode;
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFiltered = (inheritedAutoSizeColumnCriteria & autoSizeColumnCriteriaFilter);
if (autoSizeColumnCriteriaFiltered != 0)
{
ret |= AutoResizeColumnInternal(dataGridViewColumn.Index, inheritedAutoSizeColumnCriteria, fixedHeight);
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
return ret;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumn0"]/*' />
public void AutoResizeColumn(int columnIndex)
{
AutoResizeColumn(columnIndex, DataGridViewAutoSizeColumnMode.AllCells);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumn1"]/*' />
public void AutoResizeColumn(int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode)
{
AutoResizeColumn(columnIndex, autoSizeColumnMode, true);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumn2"]/*' />
protected void AutoResizeColumn(int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode, bool fixedHeight)
{
if (autoSizeColumnMode == DataGridViewAutoSizeColumnMode.NotSet ||
autoSizeColumnMode == DataGridViewAutoSizeColumnMode.None ||
autoSizeColumnMode == DataGridViewAutoSizeColumnMode.Fill)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_NeedColumnAutoSizingCriteria, "autoSizeColumnMode"));
}
switch (autoSizeColumnMode)
{
case DataGridViewAutoSizeColumnMode.NotSet:
case DataGridViewAutoSizeColumnMode.None:
case DataGridViewAutoSizeColumnMode.ColumnHeader:
case DataGridViewAutoSizeColumnMode.AllCellsExceptHeader:
case DataGridViewAutoSizeColumnMode.AllCells:
case DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader:
case DataGridViewAutoSizeColumnMode.DisplayedCells:
case DataGridViewAutoSizeColumnMode.Fill:
break;
default:
throw new InvalidEnumArgumentException("autoSizeColumnMode", (int)autoSizeColumnMode, typeof(DataGridViewAutoSizeColumnMode));
}
if (columnIndex < 0 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (autoSizeColumnMode == DataGridViewAutoSizeColumnMode.ColumnHeader && !this.ColumnHeadersVisible)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAutoSizeInvisibleColumnHeader));
}
AutoResizeColumnInternal(columnIndex, (DataGridViewAutoSizeColumnCriteriaInternal) autoSizeColumnMode, fixedHeight);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumnHeadersHeight1"]/*' />
public void AutoResizeColumnHeadersHeight()
{
AutoResizeColumnHeadersHeight(true, true);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumnHeadersHeight2"]/*' />
public void AutoResizeColumnHeadersHeight(int columnIndex)
{
AutoResizeColumnHeadersHeight(columnIndex, true, true);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumnHeadersHeight3"]/*' />
protected void AutoResizeColumnHeadersHeight(bool fixedRowHeadersWidth, bool fixedColumnsWidth)
{
if (!this.ColumnHeadersVisible)
{
return;
}
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return;
}
try
{
this.noAutoSizeCount++;
// Use of WindowsFormsUtils.CreateMeasurementGraphics() avoid use of this.Handle
// IntPtr handle = this.Handle; // Force creation of control's handle because for databound grids, handle creation wipes out and recreates the columns/rows.
int preferredHeight = 0;
if (this.layout.TopLeftHeader.Width > 0)
{
if (fixedRowHeadersWidth)
{
preferredHeight = this.TopLeftHeaderCell.GetPreferredHeight(-1, this.layout.TopLeftHeader.Width);
}
else
{
preferredHeight = this.TopLeftHeaderCell.GetPreferredSize(-1).Height;
}
}
int columnsCount = this.Columns.Count;
for (int columnIndex = 0; columnIndex < columnsCount; columnIndex++)
{
if (this.Columns[columnIndex].Visible)
{
if (fixedColumnsWidth)
{
preferredHeight = Math.Max(preferredHeight, this.Columns[columnIndex].HeaderCell.GetPreferredHeight(-1, this.Columns[columnIndex].Thickness));
}
else
{
preferredHeight = Math.Max(preferredHeight, this.Columns[columnIndex].HeaderCell.GetPreferredSize(-1).Height);
}
}
}
if (preferredHeight < minimumColumnHeadersHeight)
{
preferredHeight = minimumColumnHeadersHeight;
}
if (preferredHeight > maxHeadersThickness)
{
preferredHeight = maxHeadersThickness;
}
if (preferredHeight != this.ColumnHeadersHeight)
{
SetColumnHeadersHeightInternal(preferredHeight, !fixedColumnsWidth /*invalidInAdjustFillingColumns*/);
}
}
finally
{
Debug.Assert(this.noAutoSizeCount > 0);
this.noAutoSizeCount--;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumnHeadersHeight4"]/*' />
protected void AutoResizeColumnHeadersHeight(int columnIndex, bool fixedRowHeadersWidth, bool fixedColumnWidth)
{
if (columnIndex < -1 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (!this.ColumnHeadersVisible)
{
return;
}
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return;
}
try
{
this.noAutoSizeCount++;
// Use of WindowsFormsUtils.CreateMeasurementGraphics() avoid use of this.Handle
// IntPtr handle = this.Handle; // Force creation of control's handle because for databound grids, handle creation wipes out and recreates the columns/rows.
int preferredHeight = 0;
if (this.layout.TopLeftHeader.Width > 0)
{
if (columnIndex != -1 || fixedRowHeadersWidth)
{
preferredHeight = this.TopLeftHeaderCell.GetPreferredHeight(-1, this.layout.TopLeftHeader.Width);
}
else
{
preferredHeight = this.TopLeftHeaderCell.GetPreferredSize(-1).Height;
}
}
int columnsCount = this.Columns.Count;
for (int columnIndexTmp = 0; columnIndexTmp < columnsCount; columnIndexTmp++)
{
if (this.Columns[columnIndexTmp].Visible)
{
if (columnIndex != columnIndexTmp || fixedColumnWidth)
{
preferredHeight = Math.Max(preferredHeight, this.Columns[columnIndexTmp].HeaderCell.GetPreferredHeight(-1, this.Columns[columnIndexTmp].Thickness));
}
else
{
preferredHeight = Math.Max(preferredHeight, this.Columns[columnIndexTmp].HeaderCell.GetPreferredSize(-1).Height);
}
}
}
if (preferredHeight < minimumColumnHeadersHeight)
{
preferredHeight = minimumColumnHeadersHeight;
}
if (preferredHeight > maxHeadersThickness)
{
preferredHeight = maxHeadersThickness;
}
if (preferredHeight != this.ColumnHeadersHeight)
{
SetColumnHeadersHeightInternal(preferredHeight, !fixedColumnWidth /*invalidInAdjustFillingColumns*/);
}
}
finally
{
Debug.Assert(this.noAutoSizeCount > 0);
this.noAutoSizeCount--;
}
}
private bool AutoResizeColumnInternal(int columnIndex, DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal, bool fixedHeight)
{
Debug.Assert(autoSizeColumnCriteriaInternal == DataGridViewAutoSizeColumnCriteriaInternal.Header ||
autoSizeColumnCriteriaInternal == DataGridViewAutoSizeColumnCriteriaInternal.AllRows ||
autoSizeColumnCriteriaInternal == DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows ||
autoSizeColumnCriteriaInternal == (DataGridViewAutoSizeColumnCriteriaInternal.Header | DataGridViewAutoSizeColumnCriteriaInternal.AllRows) ||
autoSizeColumnCriteriaInternal == (DataGridViewAutoSizeColumnCriteriaInternal.Header | DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows));
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count);
Debug.Assert(autoSizeColumnCriteriaInternal != DataGridViewAutoSizeColumnCriteriaInternal.Header || this.ColumnHeadersVisible);
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return false;
}
bool ret = false; // No autosizing occurs by default.
try
{
this.noAutoSizeCount++;
// Use of WindowsFormsUtils.CreateMeasurementGraphics() avoid use of this.Handle
// IntPtr handle = this.Handle; // Force creation of control's handle because for databound grids, handle creation wipes out and recreates the columns.
// Note: Even none-resizable column can programmatically be resized.
DataGridViewColumn dataGridViewColumn = this.Columns[columnIndex];
int preferredColumnWidth = dataGridViewColumn.GetPreferredWidth((DataGridViewAutoSizeColumnMode) autoSizeColumnCriteriaInternal, fixedHeight);
if (preferredColumnWidth < dataGridViewColumn.MinimumThickness)
{
preferredColumnWidth = dataGridViewColumn.MinimumThickness;
}
if (preferredColumnWidth > DataGridViewBand.maxBandThickness)
{
preferredColumnWidth = DataGridViewBand.maxBandThickness;
}
if (preferredColumnWidth != dataGridViewColumn.Thickness)
{
if (dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
AdjustFillingColumn(dataGridViewColumn, preferredColumnWidth);
}
else
{
this.Columns[columnIndex].ThicknessInternal = preferredColumnWidth;
}
ret = true;
}
}
finally
{
Debug.Assert(this.noAutoSizeCount > 0);
this.noAutoSizeCount--;
}
return ret;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumns0"]/*' />
public void AutoResizeColumns()
{
AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumns1"]/*' />
public void AutoResizeColumns(DataGridViewAutoSizeColumnsMode autoSizeColumnsMode)
{
AutoResizeColumns(autoSizeColumnsMode, true);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeColumns2"]/*' />
protected void AutoResizeColumns(DataGridViewAutoSizeColumnsMode autoSizeColumnsMode, bool fixedHeight)
{
for (int columnIndex = 0; columnIndex < this.Columns.Count; columnIndex++)
{
AutoResizeColumn(columnIndex, (DataGridViewAutoSizeColumnMode)autoSizeColumnsMode, fixedHeight);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRow0"]/*' />
public void AutoResizeRow(int rowIndex)
{
AutoResizeRow(rowIndex, DataGridViewAutoSizeRowMode.AllCells);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRow1"]/*' />
public void AutoResizeRow(int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode)
{
AutoResizeRow(rowIndex, autoSizeRowMode, true /*fixedWidth*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRow2"]/*' />
protected void AutoResizeRow(int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
{
if (rowIndex < 0 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
// not using ClientUtils here because it's a flags enum, masking instead.
if (((DataGridViewAutoSizeRowCriteriaInternal) autoSizeRowMode & invalidDataGridViewAutoSizeRowCriteriaInternalMask) != 0)
{
throw new InvalidEnumArgumentException("autoSizeRowMode", (int) autoSizeRowMode, typeof(DataGridViewAutoSizeRowMode));
}
if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader && !this.RowHeadersVisible)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAutoSizeRowInvisibleRowHeader));
}
AutoResizeRowInternal(rowIndex, autoSizeRowMode, fixedWidth, false /*internalAutosizing*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRowHeadersWidth1"]/*' />
// User can override this if there is a quicker way to determine preferred row headers width
public void AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode)
{
AutoResizeRowHeadersWidth(rowHeadersWidthSizeMode,
true /*fixedColumnHeadersHeight*/,
true /*fixedRowsHeight*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRowHeadersWidth2"]/*' />
// User can override this if there is a quicker way to determine preferred row headers width
protected void AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode,
bool fixedColumnHeadersHeight,
bool fixedRowsHeight)
{
if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing ||
rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.DisableResizing)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_NeedAutoSizingCriteria, "rowHeadersWidthSizeMode"));
}
// custom range checking, not using ClientUtils.
if (rowHeadersWidthSizeMode < DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders || rowHeadersWidthSizeMode > DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader)
{
throw new InvalidEnumArgumentException("rowHeadersWidthSizeMode", (int)rowHeadersWidthSizeMode, typeof(DataGridViewRowHeadersWidthSizeMode));
}
if (!this.RowHeadersVisible)
{
return;
}
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return;
}
try
{
this.noAutoSizeCount++;
// Use of WindowsFormsUtils.CreateMeasurementGraphics() avoid use of this.Handle
// IntPtr handle = this.Handle; // Force creation of control's handle because for databound grids, handle creation wipes out and recreates the columns/rows.
int preferredWidth = 0, rowIndex;
if (this.layout.TopLeftHeader.Width > 0)
{
if (fixedColumnHeadersHeight)
{
preferredWidth = this.TopLeftHeaderCell.GetPreferredWidth(-1, this.layout.TopLeftHeader.Height);
}
else
{
preferredWidth = this.TopLeftHeaderCell.GetPreferredSize(-1).Width;
}
}
switch (rowHeadersWidthSizeMode)
{
case DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader:
{
rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (rowIndex != -1)
{
if (fixedRowsHeight)
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndex).HeaderCell.GetPreferredWidth(rowIndex, this.Rows.SharedRow(rowIndex).GetHeight(rowIndex)));
}
else
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndex).HeaderCell.GetPreferredSize(rowIndex).Width);
}
}
break;
}
case DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders:
{
int displayHeight = this.layout.Data.Height, cy = 0;
rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (rowIndex != -1 && cy < displayHeight)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
int dataGridViewRowHeight = dataGridViewRow.GetHeight(rowIndex);
cy += dataGridViewRowHeight;
if (fixedRowsHeight)
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredWidth(rowIndex, dataGridViewRowHeight));
}
else
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredSize(rowIndex).Width);
}
rowIndex = this.Rows.GetNextRow(rowIndex,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
if (cy < displayHeight)
{
rowIndex = this.displayedBandsInfo.FirstDisplayedScrollingRow;
while (rowIndex != -1 && cy < displayHeight)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
int dataGridViewRowHeight = dataGridViewRow.GetHeight(rowIndex);
cy += dataGridViewRowHeight;
if (fixedRowsHeight)
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredWidth(rowIndex, dataGridViewRowHeight));
}
else
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredSize(rowIndex).Width);
}
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
}
break;
}
case DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders:
{
for (rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
if (fixedRowsHeight)
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndex).HeaderCell.GetPreferredWidth(rowIndex, this.Rows.SharedRow(rowIndex).GetHeight(rowIndex)));
}
else
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndex).HeaderCell.GetPreferredSize(rowIndex).Width);
}
}
break;
}
default:
{
Debug.Fail("Unexpected rowHeadersWidthSizeMode value in AutoResizeRowHeadersWidth");
break;
}
}
if (preferredWidth < minimumRowHeadersWidth)
{
preferredWidth = minimumRowHeadersWidth;
}
if (preferredWidth != this.RowHeadersWidth)
{
this.RowHeadersWidthInternal = preferredWidth;
}
}
finally
{
Debug.Assert(this.noAutoSizeCount > 0);
this.noAutoSizeCount--;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRowHeadersWidth3"]/*' />
public void AutoResizeRowHeadersWidth(int rowIndex, DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode)
{
AutoResizeRowHeadersWidth(rowIndex,
rowHeadersWidthSizeMode,
true /*fixedColumnHeadersHeight*/,
true /*fixedRowHeight*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRowHeadersWidth4"]/*' />
protected void AutoResizeRowHeadersWidth(int rowIndex,
DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode,
bool fixedColumnHeadersHeight,
bool fixedRowHeight)
{
if (rowIndex < -1 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing ||
rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.DisableResizing)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_NeedAutoSizingCriteria, "rowHeadersWidthSizeMode"));
}
if (rowHeadersWidthSizeMode < DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders || rowHeadersWidthSizeMode > DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader)
{
throw new InvalidEnumArgumentException("rowHeadersWidthSizeMode", (int)rowHeadersWidthSizeMode, typeof(DataGridViewRowHeadersWidthSizeMode));
}
if (!this.RowHeadersVisible)
{
return;
}
if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader &&
rowIndex != -1 &&
rowIndex != this.Rows.GetFirstRow(DataGridViewElementStates.Visible))
{
return;
}
if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders &&
rowIndex != -1)
{
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
bool rowDisplayed = (rowState & DataGridViewElementStates.Displayed) != 0;
if (!rowDisplayed)
{
return;
}
}
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return;
}
try
{
this.noAutoSizeCount++;
// Use of WindowsFormsUtils.CreateMeasurementGraphics() avoid use of this.Handle
// IntPtr handle = this.Handle; // Force creation of control's handle because for databound grids, handle creation wipes out and recreates the columns/rows.
int preferredWidth = 0, rowIndexTmp;
if (this.layout.TopLeftHeader.Width > 0)
{
if (rowIndex != -1 || fixedColumnHeadersHeight)
{
preferredWidth = this.TopLeftHeaderCell.GetPreferredWidth(-1, this.layout.TopLeftHeader.Height);
}
else
{
preferredWidth = this.TopLeftHeaderCell.GetPreferredSize(-1).Width;
}
}
switch (rowHeadersWidthSizeMode)
{
case DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader:
{
rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (rowIndexTmp != -1)
{
if (rowIndex != rowIndexTmp || fixedRowHeight)
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndexTmp).HeaderCell.GetPreferredWidth(rowIndexTmp, this.Rows.SharedRow(rowIndexTmp).GetHeight(rowIndexTmp)));
}
else
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndexTmp).HeaderCell.GetPreferredSize(rowIndexTmp).Width);
}
}
break;
}
case DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders:
{
int displayHeight = this.layout.Data.Height, cy = 0;
rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (rowIndexTmp != -1 && cy < displayHeight)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndexTmp);
int dataGridViewRowHeight = dataGridViewRow.GetHeight(rowIndexTmp);
cy += dataGridViewRowHeight;
if (rowIndex != rowIndexTmp || fixedRowHeight)
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredWidth(rowIndexTmp, dataGridViewRowHeight));
}
else
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredSize(rowIndexTmp).Width);
}
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
if (cy < displayHeight)
{
rowIndexTmp = this.displayedBandsInfo.FirstDisplayedScrollingRow;
while (rowIndexTmp != -1 && cy < displayHeight)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndexTmp);
int dataGridViewRowHeight = dataGridViewRow.GetHeight(rowIndexTmp);
cy += dataGridViewRowHeight;
if (rowIndex != rowIndexTmp || fixedRowHeight)
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredWidth(rowIndexTmp, dataGridViewRowHeight));
}
else
{
preferredWidth = Math.Max(preferredWidth, dataGridViewRow.HeaderCell.GetPreferredSize(rowIndexTmp).Width);
}
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
}
}
break;
}
case DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders:
{
for (rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndexTmp != -1;
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible))
{
if (rowIndex != rowIndexTmp || fixedRowHeight)
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndexTmp).HeaderCell.GetPreferredWidth(rowIndexTmp, this.Rows.SharedRow(rowIndexTmp).GetHeight(rowIndexTmp)));
}
else
{
preferredWidth = Math.Max(preferredWidth, this.Rows.SharedRow(rowIndexTmp).HeaderCell.GetPreferredSize(rowIndexTmp).Width);
}
}
break;
}
default:
{
Debug.Fail("Unexpected rowHeadersWidthSizeMode value in AutoResizeRowHeadersWidth");
break;
}
}
if (preferredWidth < minimumRowHeadersWidth)
{
preferredWidth = minimumRowHeadersWidth;
}
if (preferredWidth != this.RowHeadersWidth)
{
this.RowHeadersWidthInternal = preferredWidth;
}
}
finally
{
Debug.Assert(this.noAutoSizeCount > 0);
this.noAutoSizeCount--;
}
}
private void AutoResizeRowInternal(int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth, bool internalAutosizing)
{
Debug.Assert(rowIndex >= 0 && rowIndex < this.Rows.Count);
Debug.Assert(((DataGridViewAutoSizeRowCriteriaInternal) autoSizeRowMode & invalidDataGridViewAutoSizeRowCriteriaInternalMask) == 0);
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return;
}
try
{
this.noAutoSizeCount++;
// Use of WindowsFormsUtils.CreateMeasurementGraphics() avoid use of this.Handle
// IntPtr handle = this.Handle; // Force creation of control's handle because for databound grids, handle creation wipes out and recreates the columns/rows.
// Note: Even none-resizable row can programmatically be resized.
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
int height, minimumHeight;
dataGridViewRow.GetHeightInfo(rowIndex, out height, out minimumHeight);
int preferredThickness = dataGridViewRow.GetPreferredHeight(rowIndex, autoSizeRowMode, fixedWidth);
if (preferredThickness < minimumHeight)
{
preferredThickness = minimumHeight;
}
if (preferredThickness > DataGridViewBand.maxBandThickness)
{
preferredThickness = DataGridViewBand.maxBandThickness;
}
if (height != preferredThickness)
{
if (this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
if (!OnRowHeightInfoPushed(rowIndex, preferredThickness, minimumHeight))
{
this.Rows[rowIndex].ThicknessInternal = preferredThickness; // unsharing the resized row
}
}
else
{
if (internalAutosizing)
{
this.Rows[rowIndex].ThicknessInternal = preferredThickness; // unsharing the resized row
}
else
{
this.Rows[rowIndex].Thickness = preferredThickness; // unsharing the resized row
}
}
}
}
finally
{
Debug.Assert(this.noAutoSizeCount > 0);
this.noAutoSizeCount--;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRows0"]/*' />
public void AutoResizeRows()
{
AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRows1"]/*' />
public void AutoResizeRows(DataGridViewAutoSizeRowsMode autoSizeRowsMode)
{
AutoResizeRows(autoSizeRowsMode, true /*fixedWidth*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRows2"]/*' />
protected void AutoResizeRows(DataGridViewAutoSizeRowsMode autoSizeRowsMode, bool fixedWidth)
{
switch (autoSizeRowsMode)
{
case DataGridViewAutoSizeRowsMode.None:
case DataGridViewAutoSizeRowsMode.AllHeaders:
case DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders:
case DataGridViewAutoSizeRowsMode.AllCells:
case DataGridViewAutoSizeRowsMode.DisplayedHeaders:
case DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders:
case DataGridViewAutoSizeRowsMode.DisplayedCells:
break;
default:
throw new InvalidEnumArgumentException("value", (int)autoSizeRowsMode, typeof(DataGridViewAutoSizeRowsMode));
}
if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_NeedAutoSizingCriteria, "autoSizeRowsMode"));
}
if ((autoSizeRowsMode == DataGridViewAutoSizeRowsMode.AllHeaders || autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedHeaders) &&
!this.RowHeadersVisible)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAutoSizeRowsInvisibleRowHeader));
}
AdjustShrinkingRows(autoSizeRowsMode, fixedWidth, false /*internalAutosizing*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.AutoResizeRows3"]/*' />
protected void AutoResizeRows(int rowIndexStart, int rowsCount, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
{
// not using ClientUtils.IsEnumValid here because DataGridViewAutoSizeRowCriteriaInternal is a flags enum.
if (((DataGridViewAutoSizeRowCriteriaInternal) autoSizeRowMode & invalidDataGridViewAutoSizeRowCriteriaInternalMask) != 0)
{
throw new InvalidEnumArgumentException("autoSizeRowMode", (int) autoSizeRowMode, typeof(DataGridViewAutoSizeRowMode));
}
if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader && !this.RowHeadersVisible)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAutoSizeRowsInvisibleRowHeader));
}
if (rowsCount < 0)
{
throw new ArgumentOutOfRangeException("rowsCount");
}
if (rowIndexStart < 0)
{
throw new ArgumentOutOfRangeException("rowIndexStart");
}
if (!this.IsHandleCreated)
{
// auto sizing causes handle creation.
// don't create the handle inside InitializeComponent because that causes problems w/ data binding
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = true;
return;
}
this.inBulkPaintCount++;
this.inBulkLayoutCount++;
try
{
int rowIndex = this.Rows.GetNextRow(rowIndexStart - 1, DataGridViewElementStates.Visible);
int autoSizedCount = 0;
while (rowIndex != -1 && autoSizedCount < rowsCount)
{
AutoResizeRowInternal(rowIndex, autoSizeRowMode, fixedWidth, false /*internalAutosizing*/);
autoSizedCount++;
if (autoSizedCount < rowsCount)
{
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
}
}
finally
{
ExitBulkLayout(true /*invalidInAdjustFillingColumns*/);
ExitBulkPaint(-1, -1);
}
}
private void BeginColumnHeadersResize(int mouseY, int mouseBarOffset)
{
if (this.IsKeyboardOperationActive())
{
return;
}
Rectangle clip = Rectangle.Union(this.layout.ColumnHeaders, this.layout.Data);
if (this.layout.TopLeftHeader.Width > 0)
{
clip = Rectangle.Union(this.layout.TopLeftHeader, clip);
}
clip.Y += minimumColumnHeadersHeight - mouseBarOffset - 1;
// No need to limit the bottom edge of the cursor clip since maxHeadersThickness is very large.
CaptureMouse(clip);
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize] = true;
this.trackRowAnchor = mouseY;
this.mouseBarOffset = mouseBarOffset;
Debug.Assert(this.lastRowSplitBar == -1);
this.currentRowSplitBar = mouseY;
Invalidate(CalcRowResizeFeedbackRect(this.currentRowSplitBar));
}
private void BeginColumnRelocation(int mouseX, int index)
{
if (this.IsKeyboardOperationActive())
{
return;
}
Rectangle cursorClip = this.layout.ColumnHeaders;
int frozenWidth = this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
int scrollingWidth = this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) - frozenWidth;
if (this.Columns[index].Frozen)
{
// A frozen column cannot be relocated into an unfrozen area
if (this.RightToLeftInternal)
{
cursorClip.X += cursorClip.Width - frozenWidth;
}
cursorClip.Width = Math.Min(frozenWidth, this.layout.Data.Width);
}
else
{
// An unfrozen column cannot be relocated into a frozen area
if (!this.RightToLeftInternal)
{
cursorClip.X += frozenWidth;
}
else if (this.layout.Data.Width > frozenWidth + scrollingWidth)
{
cursorClip.X += this.layout.Data.Width - frozenWidth - scrollingWidth;
}
cursorClip.Width = Math.Min(scrollingWidth, this.layout.Data.Width);
}
CaptureMouse(cursorClip);
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation] = true;
this.dataGridViewState2[DATAGRIDVIEWSTATE2_showColumnRelocationInsertion] = false;
this.trackColumn = index;
this.trackColumnEdge = -1;
this.mouseBarOffset = GetColumnXFromIndex(index) - mouseX;
this.lastHeaderShadow = mouseX;
Invalidate(this.layout.ColumnHeaders);
}
private void BeginColumnResize(int x, int columnIndex)
{
this.trackColAnchor = x;
this.trackColumn = columnIndex;
this.currentColSplitBar = x;
Invalidate(CalcColResizeFeedbackRect(this.currentColSplitBar));
}
private void BeginMouseColumnResize(int mouseX, int mouseBarOffset, int index)
{
if (this.IsKeyboardOperationActive())
{
return;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColResize] = true;
this.mouseBarOffset = mouseBarOffset;
this.resizeClipRectangle = GetResizeClipRectangle(index);
CaptureMouse(this.resizeClipRectangle);
BeginColumnResize(mouseX, index);
}
private void BeginKeyboardColumnResize(int columnIndex)
{
if (this.IsMouseOperationActive())
{
return;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_trackKeyboardColResize] = true;
this.mouseBarOffset = 0;
this.resizeClipRectangle = GetResizeClipRectangle(columnIndex);
this.keyboardResizeStep = this.ScaleToCurrentDpi(this.RightToLeftInternal ? -1 : 1);
int x = GetColumnXFromIndex(columnIndex);
x += this.RightToLeftInternal ? -this.Columns[columnIndex].Width : this.Columns[columnIndex].Width;
BeginColumnResize(x, columnIndex);
}
private Rectangle GetResizeClipRectangle(int columnIndex)
{
Rectangle clip = Rectangle.Union(this.layout.ColumnHeaders, this.layout.Data);
int leftEdge = GetColumnXFromIndex(columnIndex);
if (this.RightToLeftInternal)
{
clip.X = this.layout.Data.X - this.mouseBarOffset - 1;
clip.Width = leftEdge - this.Columns[columnIndex].MinimumThickness - this.layout.Data.X + 3;
int overflowWidth = leftEdge - this.mouseBarOffset - clip.Left - DataGridViewBand.maxBandThickness + 1;
if (overflowWidth > 0)
{
clip.X += overflowWidth;
clip.Width -= overflowWidth;
}
}
else
{
clip.X = leftEdge + this.Columns[columnIndex].MinimumThickness - this.mouseBarOffset - 1;
clip.Width = this.layout.Data.Right - leftEdge - 1;
int overflowWidth = clip.Right + this.mouseBarOffset - leftEdge - DataGridViewBand.maxBandThickness;
if (overflowWidth > 0)
{
clip.Width -= overflowWidth;
}
}
return clip;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.BeginEdit"]/*' />
public virtual bool BeginEdit(bool selectAll)
{
if (this.ptCurrentCell.X == -1)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_NoCurrentCell));
}
if (this.IsCurrentCellInEditMode)
{
return true;
}
return BeginEditInternal(selectAll);
}
private bool BeginEditInternal(bool selectAll)
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inBeginEdit])
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_BeginEditNotReentrant));
}
try
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inBeginEdit] = true;
Debug.Assert(this.ptCurrentCell.X >= 0 && this.ptCurrentCell.X < this.Columns.Count);
Debug.Assert(this.ptCurrentCell.Y >= 0 && this.ptCurrentCell.Y < this.Rows.Count);
Debug.Assert(!this.IsCurrentCellInEditMode);
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCell != null);
if (IsSharedCellReadOnly(dataGridViewCell, this.ptCurrentCell.Y) ||
!ColumnEditable(this.ptCurrentCell.X))
{
return false;
}
Type editControlType = dataGridViewCell.EditType;
if (editControlType == null)
{
// Current cell does not have an editing control. Does it implement IDataGridViewEditingCell?
Type editingCellInterface = dataGridViewCell.GetType().GetInterface("System.Windows.Forms.IDataGridViewEditingCell");
if (editingCellInterface == null)
{
return false;
}
}
DataGridViewCellCancelEventArgs dgvcce = new DataGridViewCellCancelEventArgs(this.ptCurrentCell.X, this.ptCurrentCell.Y);
OnCellBeginEdit(dgvcce);
if (dgvcce.Cancel)
{
return false;
}
Debug.Assert(!this.IsCurrentCellInEditMode);
if (this.ptCurrentCell.X > -1)
{
DataGridViewCell previousCurrentCell = dataGridViewCell;
dataGridViewCell = this.CurrentCellInternal;
if (previousCurrentCell != dataGridViewCell)
{
// VSWhidbey 555494. The new current cell can be a whole different cell.
// In that case, all tests previously done are no longer valid.
if (IsSharedCellReadOnly(dataGridViewCell, this.ptCurrentCell.Y) ||
!ColumnEditable(this.ptCurrentCell.X))
{
return false;
}
editControlType = dataGridViewCell.EditType;
if (editControlType == null)
{
// Current cell does not have an editing control. Does it implement IDataGridViewEditingCell?
Type editingCellInterface = dataGridViewCell.GetType().GetInterface("System.Windows.Forms.IDataGridViewEditingCell");
if (editingCellInterface == null)
{
return false;
}
}
}
}
else
{
return false;
}
DataGridViewCellStyle dataGridViewCellStyle = dataGridViewCell.GetInheritedStyle(null, this.ptCurrentCell.Y, true);
if (editControlType == null)
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode] = true;
InitializeEditingCellValue(ref dataGridViewCellStyle, ref dataGridViewCell);
((IDataGridViewEditingCell)dataGridViewCell).PrepareEditingCellForEdit(selectAll);
return true;
}
Type editingCtrlInterface = editControlType.GetInterface("System.Windows.Forms.IDataGridViewEditingControl");
if (!editControlType.IsSubclassOf(Type.GetType("System.Windows.Forms.Control")) ||
editingCtrlInterface == null)
{
throw new InvalidCastException(SR.GetString(SR.DataGridView_InvalidEditingControl));
}
if (this.latestEditingControl != null &&
editControlType.IsInstanceOfType(this.latestEditingControl) &&
!this.latestEditingControl.GetType().IsSubclassOf(editControlType))
{
this.editingControl = this.latestEditingControl;
Debug.Assert(((IDataGridViewEditingControl)this.editingControl).EditingControlDataGridView == this);
}
else
{
Debug.Assert(this.editingControl == null);
this.editingControl = (Control)SecurityUtils.SecureCreateInstance(editControlType);
Debug.Assert(this.editingControl != null);
((IDataGridViewEditingControl)this.editingControl).EditingControlDataGridView = this;
if (this.latestEditingControl != null)
{
this.latestEditingControl.Dispose();
this.latestEditingControl = null;
}
}
Debug.Assert(this.editingControl != null);
if (String.IsNullOrEmpty(this.editingControl.AccessibleName))
{
this.editingControl.AccessibleName = SR.GetString(SR.DataGridView_AccEditingControlAccName);
}
this.editingControl.ImeMode = this.ImeMode;
((IDataGridViewEditingControl)this.editingControl).EditingControlRowIndex = this.ptCurrentCell.Y;
InitializeEditingControlValue(ref dataGridViewCellStyle, dataGridViewCell);
WireEditingControlEvents();
Debug.Assert(this.editingControl != null);
Debug.Assert(this.editingPanel != null);
DataGridViewEditingControlShowingEventArgs dgvese = new DataGridViewEditingControlShowingEventArgs(this.editingControl, dataGridViewCellStyle);
OnEditingControlShowing(dgvese);
Debug.Assert(dgvese.CellStyle != null);
if (this.editingPanel == null || this.editingControl == null)
{
return false;
}
this.editingPanel.BackColor = dgvese.CellStyle.BackColor;
((IDataGridViewEditingControl)this.editingControl).ApplyCellStyleToEditingControl(dgvese.CellStyle);
// Get rid of the tooltip if it's showing for the current cell
if (this.toolTipControl.Activated && this.ptToolTipCell == this.ptCurrentCell)
{
this.toolTipControl.Activate(false /*activate*/);
}
PositionEditingControl(true, true, true);
// Guarding against bugs in customer code.
// For example setting the CurrentCell to null in DataGridView_OnLostFocus(...) causes this.editingControl
// to become null.
if (this.editingPanel == null || this.editingControl == null)
{
return false;
}
else
{
((IDataGridViewEditingControl)this.editingControl).PrepareEditingControlForEdit(selectAll);
InvalidateCellPrivate(this.ptCurrentCell.X, this.ptCurrentCell.Y);
return true;
}
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inBeginEdit] = false;
}
}
private void BeginRowHeadersResize(int mouseX, int mouseBarOffset)
{
if (this.IsKeyboardOperationActive())
{
return;
}
Rectangle clip = Rectangle.Union(this.layout.RowHeaders, this.layout.Data);
if (this.layout.TopLeftHeader.Width > 0)
{
clip = Rectangle.Union(this.layout.TopLeftHeader, clip);
}
if (this.RightToLeftInternal)
{
clip.X -= mouseBarOffset + 1;
clip.Width -= minimumRowHeadersWidth - 1;
// No need to limit the left edge of the cursor clip since maxHeadersThickness is very large.
}
else
{
clip.X += minimumRowHeadersWidth - mouseBarOffset - 1;
// No need to limit the right edge of the cursor clip since maxHeadersThickness is very large.
}
CaptureMouse(clip);
this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize] = true;
this.trackColAnchor = mouseX;
this.mouseBarOffset = mouseBarOffset;
Debug.Assert(this.lastColSplitBar == -1);
this.currentColSplitBar = mouseX;
Invalidate(CalcColResizeFeedbackRect(this.currentColSplitBar));
}
private void BeginRowResize(int mouseY, int mouseBarOffset, int index)
{
if (this.IsKeyboardOperationActive())
{
return;
}
Rectangle clip = Rectangle.Union(this.layout.RowHeaders, this.layout.Data);
int topEdge = GetRowYFromIndex(index);
clip.Y = topEdge + this.Rows.SharedRow(index).GetMinimumHeight(index) - mouseBarOffset - 1;
clip.Height = this.layout.Data.Y + this.layout.Data.Height - topEdge - 1;
CaptureMouse(clip);
this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowResize] = true;
this.trackRowAnchor = mouseY;
this.trackRow = index;
this.mouseBarOffset = mouseBarOffset;
Debug.Assert(this.lastRowSplitBar == -1);
this.currentRowSplitBar = mouseY;
Invalidate(CalcRowResizeFeedbackRect(this.currentRowSplitBar));
}
private void BuildInheritedColumnHeaderCellStyle(DataGridViewCellStyle inheritedCellStyle, DataGridViewCell cell)
{
Debug.Assert(inheritedCellStyle != null);
DataGridViewCellStyle cellStyle = null;
if (cell.HasStyle)
{
cellStyle = cell.Style;
Debug.Assert(cellStyle != null);
}
DataGridViewCellStyle columnHeadersStyle = this.ColumnHeadersDefaultCellStyle;
Debug.Assert(columnHeadersStyle != null);
DataGridViewCellStyle dataGridViewStyle = this.DefaultCellStyle;
Debug.Assert(dataGridViewStyle != null);
if (cellStyle != null && !cellStyle.BackColor.IsEmpty)
{
inheritedCellStyle.BackColor = cellStyle.BackColor;
}
else if (!columnHeadersStyle.BackColor.IsEmpty)
{
inheritedCellStyle.BackColor = columnHeadersStyle.BackColor;
}
else
{
inheritedCellStyle.BackColor = dataGridViewStyle.BackColor;
}
if (cellStyle != null && !cellStyle.ForeColor.IsEmpty)
{
inheritedCellStyle.ForeColor = cellStyle.ForeColor;
}
else if (!columnHeadersStyle.ForeColor.IsEmpty)
{
inheritedCellStyle.ForeColor = columnHeadersStyle.ForeColor;
}
else
{
inheritedCellStyle.ForeColor = dataGridViewStyle.ForeColor;
}
if (cellStyle != null && !cellStyle.SelectionBackColor.IsEmpty)
{
inheritedCellStyle.SelectionBackColor = cellStyle.SelectionBackColor;
}
else if (!columnHeadersStyle.SelectionBackColor.IsEmpty)
{
inheritedCellStyle.SelectionBackColor = columnHeadersStyle.SelectionBackColor;
}
else
{
inheritedCellStyle.SelectionBackColor = dataGridViewStyle.SelectionBackColor;
}
if (cellStyle != null && !cellStyle.SelectionForeColor.IsEmpty)
{
inheritedCellStyle.SelectionForeColor = cellStyle.SelectionForeColor;
}
else if (!columnHeadersStyle.SelectionForeColor.IsEmpty)
{
inheritedCellStyle.SelectionForeColor = columnHeadersStyle.SelectionForeColor;
}
else
{
inheritedCellStyle.SelectionForeColor = dataGridViewStyle.SelectionForeColor;
}
if (cellStyle != null && cellStyle.Font != null)
{
inheritedCellStyle.Font = cellStyle.Font;
}
else if (columnHeadersStyle.Font != null)
{
inheritedCellStyle.Font = columnHeadersStyle.Font;
}
else
{
inheritedCellStyle.Font = dataGridViewStyle.Font;
}
if (cellStyle != null && !cellStyle.IsNullValueDefault)
{
inheritedCellStyle.NullValue = cellStyle.NullValue;
}
else if (!columnHeadersStyle.IsNullValueDefault)
{
inheritedCellStyle.NullValue = columnHeadersStyle.NullValue;
}
else
{
inheritedCellStyle.NullValue = dataGridViewStyle.NullValue;
}
if (cellStyle != null && !cellStyle.IsDataSourceNullValueDefault)
{
inheritedCellStyle.DataSourceNullValue = cellStyle.DataSourceNullValue;
}
else if (!columnHeadersStyle.IsDataSourceNullValueDefault)
{
inheritedCellStyle.DataSourceNullValue = columnHeadersStyle.DataSourceNullValue;
}
else
{
inheritedCellStyle.DataSourceNullValue = dataGridViewStyle.DataSourceNullValue;
}
if (cellStyle != null && cellStyle.Format.Length != 0)
{
inheritedCellStyle.Format = cellStyle.Format;
}
else if (columnHeadersStyle.Format.Length != 0)
{
inheritedCellStyle.Format = columnHeadersStyle.Format;
}
else
{
inheritedCellStyle.Format = dataGridViewStyle.Format;
}
if (cellStyle != null && !cellStyle.IsFormatProviderDefault)
{
inheritedCellStyle.FormatProvider = cellStyle.FormatProvider;
}
else if (!columnHeadersStyle.IsFormatProviderDefault)
{
inheritedCellStyle.FormatProvider = columnHeadersStyle.FormatProvider;
}
else
{
inheritedCellStyle.FormatProvider = dataGridViewStyle.FormatProvider;
}
if (cellStyle != null && cellStyle.Alignment != DataGridViewContentAlignment.NotSet)
{
inheritedCellStyle.AlignmentInternal = cellStyle.Alignment;
}
else if (columnHeadersStyle != null && columnHeadersStyle.Alignment != DataGridViewContentAlignment.NotSet)
{
inheritedCellStyle.AlignmentInternal = columnHeadersStyle.Alignment;
}
else
{
Debug.Assert(dataGridViewStyle.Alignment != DataGridViewContentAlignment.NotSet);
inheritedCellStyle.AlignmentInternal = dataGridViewStyle.Alignment;
}
if (cellStyle != null && cellStyle.WrapMode != DataGridViewTriState.NotSet)
{
inheritedCellStyle.WrapModeInternal = cellStyle.WrapMode;
}
else if (columnHeadersStyle != null && columnHeadersStyle.WrapMode != DataGridViewTriState.NotSet)
{
inheritedCellStyle.WrapModeInternal = columnHeadersStyle.WrapMode;
}
else
{
Debug.Assert(dataGridViewStyle.WrapMode != DataGridViewTriState.NotSet);
inheritedCellStyle.WrapModeInternal = dataGridViewStyle.WrapMode;
}
if (cellStyle != null && cellStyle.Tag != null)
{
inheritedCellStyle.Tag = cellStyle.Tag;
}
else if (columnHeadersStyle.Tag != null)
{
inheritedCellStyle.Tag = columnHeadersStyle.Tag;
}
else
{
inheritedCellStyle.Tag = dataGridViewStyle.Tag;
}
if (cellStyle != null && cellStyle.Padding != Padding.Empty)
{
inheritedCellStyle.PaddingInternal = cellStyle.Padding;
}
else if (columnHeadersStyle.Padding != Padding.Empty)
{
inheritedCellStyle.PaddingInternal = columnHeadersStyle.Padding;
}
else
{
inheritedCellStyle.PaddingInternal = dataGridViewStyle.Padding;
}
}
private Rectangle CalcColRelocationFeedbackRect(int mouseX)
{
Rectangle r, inside = this.layout.ColumnHeaders;
if (this.layout.TopLeftHeader.Width > 0)
{
inside = Rectangle.Union(this.layout.TopLeftHeader, inside);
}
if (this.RightToLeftInternal)
{
r = new Rectangle(mouseX + this.mouseBarOffset - this.Columns[this.trackColumn].Thickness + 1,
inside.Y,
this.Columns[this.trackColumn].Thickness,
inside.Height);
r.X = Math.Max(inside.Left, r.X);
r.X = Math.Min(r.X, inside.Right - r.Width);
}
else
{
r = new Rectangle(mouseX + this.mouseBarOffset - 1, inside.Y, this.Columns[this.trackColumn].Thickness, inside.Height);
r.X = Math.Min(inside.Right - r.Width, r.X);
r.X = Math.Max(r.X, inside.Left);
}
return r;
}
private Rectangle CalcColResizeFeedbackRect(int mouseX)
{
Rectangle inside = this.layout.Data;
Rectangle r = new Rectangle(mouseX + this.mouseBarOffset - 1, inside.Y, 3, inside.Height);
if (this.RightToLeftInternal)
{
r.X = Math.Max(inside.Left, r.X);
}
else
{
r.X = Math.Min(inside.Right - 3, r.X);
r.X = Math.Max(r.X, 0);
}
return r;
}
private Rectangle CalcRowResizeFeedbackRect(int mouseY)
{
Rectangle inside = this.layout.Data;
Rectangle r = new Rectangle(inside.X, mouseY + this.mouseBarOffset - 1, inside.Width, 3);
r.Y = Math.Min(inside.Bottom - 3, r.Y);
r.Y = Math.Max(r.Y, 0);
return r;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.CancelEdit"]/*' />
public bool CancelEdit()
{
return CancelEdit(false /*endEdit, DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.InitialValueRestoration*/);
}
private bool CancelEdit(bool endEdit /*, DataGridViewDataErrorContexts context*/)
{
if (this.ptCurrentCell.X != -1)
{
Debug.Assert(this.ptCurrentCell.Y != -1);
int oldCurrentCellX = this.ptCurrentCell.X;
DataGridViewDataErrorEventArgs dgvdee = CancelEditPrivate(/*ref dataGridViewCurrentCell, context*/);
if (null != dgvdee)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
if (dgvdee.Cancel)
{
return false;
}
}
if (this.IsCurrentCellInEditMode)
{
if (endEdit && this.EditMode != DataGridViewEditMode.EditOnEnter && this.editingControl != null)
{
bool success = EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.InitialValueRestoration,
DataGridViewValidateCellInternal.Never /*validateCell*/,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
true /*keepFocus*/,
true /*resetCurrentCell unused here*/,
true /*resetAnchorCell unused here*/);
Debug.Assert(success);
}
else
{
DataGridViewDataErrorEventArgs dgvdee2 = null;
IDataGridViewEditingCell dataGridViewEditingCell = null;
try
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges] = true;
if (this.editingControl != null)
{
((IDataGridViewEditingControl)this.editingControl).EditingControlFormattedValue = this.uneditedFormattedValue;
((IDataGridViewEditingControl)this.editingControl).EditingControlValueChanged = false;
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
dataGridViewEditingCell = this.CurrentCellInternal as IDataGridViewEditingCell;
Debug.Assert(dataGridViewEditingCell != null);
dataGridViewEditingCell.EditingCellFormattedValue = this.uneditedFormattedValue;
dataGridViewEditingCell.EditingCellValueChanged = false;
}
}
catch (Exception exception)
{
if (ClientUtils.IsCriticalException(exception))
{
throw;
}
dgvdee2 = new DataGridViewDataErrorEventArgs(exception, this.ptCurrentCell.X,
this.ptCurrentCell.Y,
DataGridViewDataErrorContexts.InitialValueRestoration);
}
finally
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges] = false;
}
if (dgvdee2 != null)
{
OnDataErrorInternal(dgvdee2);
if (dgvdee2.ThrowException)
{
throw dgvdee2.Exception;
}
}
if (this.editingControl != null)
{
((IDataGridViewEditingControl) this.editingControl).PrepareEditingControlForEdit(true /*selectAll*/);
}
else
{
Debug.Assert(dataGridViewEditingCell != null);
dataGridViewEditingCell.PrepareEditingCellForEdit(true /*selectAll*/);
InvalidateCellPrivate(this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
}
}
else if (this.ptCurrentCell.X == -1 && this.Focused)
{
Debug.Assert((this.AllowUserToAddRowsInternal && this.Rows.Count == 1) ||
(!this.AllowUserToAddRowsInternal && this.Rows.Count == 0));
if (this.Rows.Count > 0)
{
if (this.Columns.Count > oldCurrentCellX && this.Columns[oldCurrentCellX].Visible)
{
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (rowIndex != -1)
{
bool success = SetAndSelectCurrentCellAddress(oldCurrentCellX,
rowIndex,
true /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/,
false /*clearSelection*/,
false /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
}
else
{
MakeFirstDisplayedCellCurrentCell(true /*includeNewRow*/);
}
}
}
}
return true;
}
private DataGridViewDataErrorEventArgs CancelEditPrivate(/*ref DataGridViewCell dataGridViewCurrentCell, DataGridViewDataErrorContexts context*/)
{
bool currentCellDirty = this.IsCurrentCellDirty;
bool currentRowDirty = this.IsCurrentRowDirty;
if (this.IsCurrentCellInEditMode)
{
/* Do not push original value back into the cell - VS Whidbey bug 328624
Exception exception;
if (!PushFormattedValue(ref dataGridViewCurrentCell, this.uneditedFormattedValue, out exception))
{
Debug.Assert(dataGridViewCurrentCell.RowIndex > -1);
DataGridViewDataErrorEventArgs dgvdee = new DataGridViewDataErrorEventArgs(exception,
dataGridViewCurrentCell.ColumnIndex,
dataGridViewCurrentCell.RowIndex,
// dataGridViewCurrentCell.Value,
// this.uneditedFormattedValue,
context);
dgvdee.Cancel = true;
OnDataErrorInternal(dgvdee);
return dgvdee;
}
*/
if (this.editingControl != null)
{
((IDataGridViewEditingControl)this.editingControl).EditingControlValueChanged = false;
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
((IDataGridViewEditingCell)this.CurrentCellInternal).EditingCellValueChanged = false;
}
this.IsCurrentCellDirtyInternal = false;
}
if (this.DataSource != null || this.VirtualMode)
{
if ((currentRowDirty && !currentCellDirty) ||
(this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowEdited] &&
!this.dataGridViewState1[DATAGRIDVIEWSTATE1_editedRowChanged]))
{
bool discardNewRow = this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowEdited];
this.IsCurrentRowDirtyInternal = false;
if (this.VirtualMode)
{
QuestionEventArgs qe = new QuestionEventArgs(discardNewRow);
OnCancelRowEdit(qe);
discardNewRow &= qe.Response;
}
if (this.DataSource != null)
{
int oldCurrentCellX = this.ptCurrentCell.X;
this.dataConnection.CancelRowEdit(true /*restoreRow*/, this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowEdited]/*addNewFinished*/);
if (this.dataConnection.List.Count == 0)
{
// There are no rows left in the back end.
if (currentCellDirty || this.ptCurrentCell.Y == -1 || this.ptCurrentCell.X == -1)
{
if (!IsColumnOutOfBounds(oldCurrentCellX) && this.Columns[oldCurrentCellX].Visible)
{
Debug.Assert(0 == this.Rows.GetFirstRow(DataGridViewElementStates.Visible));
// Setting the current cell to the current column in the first row
// will create the new row if the user was editing the cell.
SetAndSelectCurrentCellAddress(oldCurrentCellX,
0,
true, /*setAnchorCellAddress*/
false, /*validateCurrentCell*/
false, /*throughMouseClick*/
true /*clearSelecttion*/,
false /*forceCurrentCellSelection (unused)*/);
}
}
else
{
// Else, simply add a new row.
this.dataConnection.OnNewRowNeeded();
}
}
// CancelRowEdit discarded the new row if we were editing the new row.
discardNewRow = false;
}
if (this.ptCurrentCell.Y > -1)
{
InvalidateRowPrivate(this.ptCurrentCell.Y);
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
if (this.IsCurrentCellInEditMode)
{
DataGridViewCellStyle dataGridViewCellStyle = dataGridViewCell.GetInheritedStyle(null, this.ptCurrentCell.Y, true);
if (this.editingControl != null)
{
InitializeEditingControlValue(ref dataGridViewCellStyle, dataGridViewCell);
if (((IDataGridViewEditingControl) this.editingControl).RepositionEditingControlOnValueChange)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
InitializeEditingCellValue(ref dataGridViewCellStyle, ref dataGridViewCell);
}
}
}
if (discardNewRow && this.ptCurrentCell.Y == this.newRowIndex - 1)
{
DiscardNewRow();
}
}
}
else
{
if (!this.IsCurrentRowDirty &&
this.ptCurrentCell.Y == this.newRowIndex - 1 &&
this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowCreatedByEditing])
{
DiscardNewRow();
}
}
return null;
}
internal bool CancelToolTipPopup(ToolTip toolTip)
{
if (this.toolTipControl.ToolTip == toolTip)
{
// Our own tool tip wants to show its text.
return false;
}
else
{
// This is an external tool tip control which wants to show a tool tip over the DataGridView.
// ToolTips from the data Grid view ( the error text, or the formatted text that does not fit in, or the tool tip text from the cell)
// and the ShowCellToolTips take precedence over the external tool tip.
return String.IsNullOrEmpty(this.toolTipCaption) && this.ShowCellToolTips;
}
}
private bool CanSort(DataGridViewColumn dataGridViewColumn)
{
return dataGridViewColumn.SortMode == DataGridViewColumnSortMode.Automatic && (!VirtualMode || dataGridViewColumn.IsDataBound);
}
private bool IsSortable(DataGridViewColumn dataGridViewColumn)
{
return dataGridViewColumn.SortMode != DataGridViewColumnSortMode.NotSortable && (!VirtualMode || dataGridViewColumn.IsDataBound);
}
// determines if a data bound cell can be validated or not
private bool CanValidateDataBoundDataGridViewCell(DataGridViewCell dataGridViewCurrentCell)
{
if (dataGridViewCurrentCell == null)
{
if (this.ptCurrentCell.X > -1)
{
dataGridViewCurrentCell = this.CurrentCellInternal;
}
}
if (dataGridViewCurrentCell == null)
{
return true;
}
Debug.Assert(dataGridViewCurrentCell.OwningColumn != null);
if (!dataGridViewCurrentCell.OwningColumn.IsDataBoundInternal)
{
// we are not data bound so it's not up to us to decide to stop validation
return true;
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose])
{
// Dispose is not the place to validate data. Also, chances are that the data source is also disposing itself.
return false;
}
if (this.dataConnection == null)
{
// if there is no dataConnection then it is not up to this function to stop validation.
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// //
// FROM HERE DOWN THE DATA CONNECTION DETERMINES IF THE DATAGRIDVIEW SHOULD VALIDATE THE CELL. //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////
if (this.dataConnection.ProcessingMetaDataChanges)
{
// don't validate a cell in a data bound column while the property descriptors change under us
return false;
}
if (this.dataConnection.CancellingRowEdit && !this.dataConnection.RestoreRow)
{
// don't validate a cell in a data bound column while we are cancelling a row edit and the old row is not restored
return false;
}
if (this.dataConnection.CurrencyManager.Count <= this.ptCurrentCell.Y)
{
// don't validate a row beyond the last row in the back end list
return false;
}
if (this.dataConnection.PositionChangingOutsideDataGridView)
{
// the position changed outside the data grid view and we haven't validated the data grid view cell already
// we can't validate it now because if the user cancels validation then we end up
// with a position different than the position in the currency manager
return false;
}
if (this.dataConnection.ListWasReset)
{
// The list was reset outside data grid view.
// We can't validate it now because we would be pushing a value into a different object ( possibly located in a different list ).
return false;
}
return true;
}
private void CaptureMouse(Rectangle cursorClip)
{
this.CaptureInternal = true;
Cursor.ClipInternal = RectangleToScreen(cursorClip);
}
private void ClearRegionCache()
{
this.cachedScrollableRegion = null;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ClearSelection"]/*' />
public void ClearSelection()
{
this.noDimensionChangeCount++;
this.noSelectionChangeCount++;
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold ||
this.individualSelectedCells.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
RemoveIndividuallySelectedCells();
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
// If we change the design and start using this.selectedBandIndexes in this SelectionMode,
// we'll have to clear those selections too.
break;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
while(this.selectedBandIndexes.Count > 0)
{
SetSelectedRowCore(this.selectedBandIndexes.HeadInt, false);
}
// Force repainting of the current collumn's header cell to remove highlighting
if (this.ptCurrentCell.X != -1 &&
this.SelectionMode == DataGridViewSelectionMode.FullRowSelect &&
AccessibilityImprovements.Level2)
{
InvalidateCellPrivate(this.ptCurrentCell.X, -1);
}
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
while(this.selectedBandIndexes.Count > 0)
{
SetSelectedColumnCore(this.selectedBandIndexes.HeadInt, false);
}
break;
}
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
this.NoSelectionChangeCount--;
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ClearSelection2"]/*' />
protected void ClearSelection(int columnIndexException, int rowIndexException, bool selectExceptionElement)
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
if (columnIndexException < 0 || columnIndexException >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndexException");
}
break;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
if (columnIndexException < -1 || columnIndexException >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndexException");
}
break;
}
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
if (rowIndexException < 0 || rowIndexException >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndexException");
}
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
if (rowIndexException < -1 || rowIndexException >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndexException");
}
break;
}
}
// Clears all selection except the row/column/cell specified as parameter
this.noDimensionChangeCount++;
this.noSelectionChangeCount++;
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold ||
this.individualSelectedCells.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
// If we change the design and start using this.selectedBandIndexes in this SelectionMode,
// we'll have to clear those selections too.
RemoveIndividuallySelectedCells(columnIndexException, rowIndexException);
break;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
int bandIndex = 0;
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != rowIndexException)
{
// deselect currently selected row
SetSelectedRowCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
if (this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect)
{
RemoveIndividuallySelectedCells(columnIndexException, rowIndexException);
}
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
int bandIndex = 0;
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != columnIndexException)
{
// deselect currently selected column
SetSelectedColumnCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
if (this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect)
{
RemoveIndividuallySelectedCells(columnIndexException, rowIndexException);
}
break;
}
}
if (selectExceptionElement)
{
SetSelectedElementCore(columnIndexException, rowIndexException, true);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
this.NoSelectionChangeCount--;
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
private bool ColumnEditable(int columnIndex)
{
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count, "Invalid columnIndex: " + columnIndex );
if (this.Columns[columnIndex].IsDataBound &&
this.dataConnection != null &&
!this.dataConnection.AllowEdit)
{
return false;
}
return true;
}
private bool ColumnNeedsDisplayedState(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
if (!dataGridViewColumn.Visible)
{
return false;
}
if (dataGridViewColumn.Frozen)
{
DataGridViewColumn firstVisibleFrozenColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
Debug.Assert(firstVisibleFrozenColumn != null);
if (firstVisibleFrozenColumn.Index == dataGridViewColumn.Index)
{
return this.displayedBandsInfo.NumDisplayedFrozenCols > 0;
}
Debug.Assert(this.Columns.DisplayInOrder(firstVisibleFrozenColumn.Index, dataGridViewColumn.Index));
return this.Columns.GetColumnCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen, firstVisibleFrozenColumn.Index, dataGridViewColumn.Index) < this.displayedBandsInfo.NumDisplayedFrozenCols;
}
else
{
int firstDisplayedScrollingColumnIndex = this.displayedBandsInfo.FirstDisplayedScrollingCol;
if (firstDisplayedScrollingColumnIndex != -1)
{
if (firstDisplayedScrollingColumnIndex == dataGridViewColumn.Index)
{
return this.displayedBandsInfo.NumDisplayedScrollingCols > 0;
}
if (this.Columns.DisplayInOrder(firstDisplayedScrollingColumnIndex, dataGridViewColumn.Index))
{
return this.Columns.GetColumnCount(DataGridViewElementStates.Visible, firstDisplayedScrollingColumnIndex, dataGridViewColumn.Index) < this.displayedBandsInfo.NumDisplayedScrollingCols;
}
}
}
return false;
}
private bool ColumnRelocationTarget(MouseEventArgs e, HitTestInfo hti, out int previousColumnIndex)
{
previousColumnIndex = -1;
if (hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeadersResizeBottom ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeader ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeRight ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeaderLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeaderRight)
{
Debug.Assert(hti.col != -1);
if (hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeadersResizeBottom ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeader)
{
int xColumnLeftEdge = GetColumnXFromIndex(hti.col);
int wColumn = this.Columns[hti.col].Width;
if ((this.RightToLeftInternal && e.X < xColumnLeftEdge - wColumn / 2) ||
(!this.RightToLeftInternal && e.X > xColumnLeftEdge + wColumn / 2))
{
// Insert column on the right of hti.col
previousColumnIndex = hti.col;
}
else
{
// Insert column on the left of hti.col
DataGridViewColumn dataGridViewColumnPrev = this.Columns.GetPreviousColumn(this.Columns[hti.col],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumnPrev != null)
{
previousColumnIndex = dataGridViewColumnPrev.Index;
}
}
}
else
{
previousColumnIndex = (hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeRight || hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeaderRight) ?
hti.col : hti.adjacentCol;
}
DataGridViewColumn dataGridViewColumnNext = null;
if (previousColumnIndex != -1)
{
dataGridViewColumnNext = this.Columns.GetNextColumn(this.Columns[previousColumnIndex],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
if (this.trackColumn != previousColumnIndex &&
!(previousColumnIndex == -1 && hti.col == this.trackColumn) &&
(dataGridViewColumnNext == null || this.trackColumn != dataGridViewColumnNext.Index))
{
return true;
}
}
else if (hti.typeInternal == DataGridViewHitTestTypeInternal.FirstColumnHeaderLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.TopLeftHeaderResizeRight)
{
Debug.Assert(hti.col != -1);
if (hti.col != this.trackColumn)
{
return true;
}
}
return false;
}
private static bool ColumnsDisplayInOrder(int columnIndex1,
int columnDisplayIndex1,
int columnIndex2,
int columnDisplayIndex2)
{
return columnDisplayIndex1 < columnDisplayIndex2 ||
(columnDisplayIndex1 == columnDisplayIndex2 && columnIndex1 < columnIndex2);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.CommitEdit"]/*' />
public bool CommitEdit(DataGridViewDataErrorContexts context)
{
if (this.IsCurrentCellInEditMode)
{
DataGridViewCell dataGridViewCurrentCell = this.CurrentCellInternal;
DataGridViewDataErrorEventArgs dgvdee = CommitEdit(ref dataGridViewCurrentCell,
context,
DataGridViewValidateCellInternal.Never,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/);
if (null != dgvdee)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
if (dgvdee.Cancel)
{
return false;
}
}
}
return true;
}
private DataGridViewDataErrorEventArgs CommitEdit(ref DataGridViewCell dataGridViewCurrentCell,
DataGridViewDataErrorContexts context,
DataGridViewValidateCellInternal validateCell,
bool fireCellLeave,
bool fireCellEnter,
bool fireRowLeave,
bool fireRowEnter,
bool fireLeave)
{
if (validateCell == DataGridViewValidateCellInternal.Always)
{
Debug.Assert(this.ptCurrentCell.X > -1);
if (fireCellLeave)
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
OnCellLeave(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
if (fireRowLeave)
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
OnRowLeave(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
if (fireLeave)
{
base.OnLeave(EventArgs.Empty);
// Microsoft: can we be smarter about this? What if validating the current cell below forces a repaint on the cell?
// we would end up repainting the current cell twice.
//
// invalidate the current cell so the data grid view does not paint the focus rectangle any longer
if (this.ptCurrentCell.X > -1 && this.ptCurrentCell.Y > -1)
{
InvalidateCellPrivate(this.ptCurrentCell.X /*columnIndex*/, this.ptCurrentCell.Y /*rowIndex*/);
}
}
// OnCellValidating returns true if the dev cancelled the validation.
bool validateFormattedValue = CanValidateDataBoundDataGridViewCell(dataGridViewCurrentCell);
if (validateFormattedValue)
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
if (OnCellValidating(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y, context))
{
if (fireRowEnter)
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
OnRowEnter(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y, true /*canCreateNewRow*/, true /*validationFailureOccurred*/);
}
if (fireCellEnter)
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
OnCellEnter(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
if (this.ptCurrentCell.X == -1)
{
return null;
}
DataGridViewDataErrorEventArgs dgvdee = new DataGridViewDataErrorEventArgs(null,
this.ptCurrentCell.X,
this.ptCurrentCell.Y,
// null,
// null,
context);
dgvdee.Cancel = true;
return dgvdee;
}
if (!this.IsCurrentCellInEditMode || !this.IsCurrentCellDirty)
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
OnCellValidated(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
}
}
if (this.ptCurrentCell.X == -1 || !this.IsCurrentCellInEditMode)
{
return null;
}
Debug.Assert(
(
(this.editingControl != null && ((IDataGridViewEditingControl)this.editingControl).EditingControlValueChanged) ||
(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode] && ((IDataGridViewEditingCell)this.CurrentCellInternal).EditingCellValueChanged)
) == this.IsCurrentCellDirty ||
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges]);
if (this.IsCurrentCellDirty)
{
bool validateAndPushFormattedValue = CanValidateDataBoundDataGridViewCell(dataGridViewCurrentCell);
if (validateAndPushFormattedValue)
{
if (validateCell == DataGridViewValidateCellInternal.WhenChanged)
{
Debug.Assert(this.ptCurrentCell.X > -1);
if (this.ptCurrentCell.X == -1)
{
return null;
}
if (OnCellValidating(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y, context))
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
DataGridViewDataErrorEventArgs dgvdee = new DataGridViewDataErrorEventArgs(null,
this.ptCurrentCell.X,
this.ptCurrentCell.Y,
context);
dgvdee.Cancel = true;
return dgvdee;
}
}
Exception exception;
object formattedValue;
if (this.editingControl != null)
{
formattedValue = ((IDataGridViewEditingControl)this.editingControl).GetEditingControlFormattedValue(context);
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
formattedValue = ((IDataGridViewEditingCell)this.CurrentCellInternal).GetEditingCellFormattedValue(context);
}
if (!PushFormattedValue(ref dataGridViewCurrentCell, formattedValue, out exception))
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
DataGridViewDataErrorEventArgs dgvdee = new DataGridViewDataErrorEventArgs(exception,
this.ptCurrentCell.X,
this.ptCurrentCell.Y,
// dataGridViewCurrentCell.Value,
// formattedValue,
context);
dgvdee.Cancel = true;
OnDataErrorInternal(dgvdee);
return dgvdee;
}
if (!this.IsCurrentCellInEditMode)
{
return null;
}
this.uneditedFormattedValue = formattedValue;
}
if (this.editingControl != null)
{
((IDataGridViewEditingControl) this.editingControl).EditingControlValueChanged = false;
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
((IDataGridViewEditingCell) this.CurrentCellInternal).EditingCellValueChanged = false;
}
this.IsCurrentCellDirtyInternal = false;
this.IsCurrentRowDirtyInternal = true;
if (validateAndPushFormattedValue)
{
if (validateCell == DataGridViewValidateCellInternal.Always ||
validateCell == DataGridViewValidateCellInternal.WhenChanged)
{
if (this.ptCurrentCell.X == -1)
{
return null;
}
OnCellValidated(ref dataGridViewCurrentCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
}
}
return null;
}
private bool CommitEdit(DataGridViewDataErrorContexts context,
bool forCurrentCellChange,
bool forCurrentRowChange)
{
// If we're already within a CellValidating event handler, don't try to commit the cell again.
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inCellValidating])
{
return false;
}
DataGridViewCell dataGridViewCurrentCell = this.CurrentCellInternal;
DataGridViewDataErrorEventArgs dgvdee = CommitEdit(ref dataGridViewCurrentCell,
context,
forCurrentCellChange ? DataGridViewValidateCellInternal.Always : DataGridViewValidateCellInternal.WhenChanged /*validateCell*/,
forCurrentCellChange /*fireCellLeave*/,
forCurrentCellChange /*fireCellEnter*/,
forCurrentRowChange /*fireRowLeave*/,
forCurrentRowChange /*fireRowEnter*/,
false /*fireLeave*/);
if (null != dgvdee)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
if (dgvdee.Cancel)
{
return false;
}
dgvdee = CancelEditPrivate(/*ref dataGridViewCurrentCell,
DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll*/); // restore old value
if (null != dgvdee)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
if (dgvdee.Cancel)
{
return false;
}
}
}
// See if we can leave the row
if (forCurrentRowChange && forCurrentCellChange)
{
Debug.Assert(this.ptCurrentCell.X > -1);
if (this.ptCurrentCell.X == -1)
{
return false;
}
int columnIndex = this.ptCurrentCell.X;
int rowIndex = this.ptCurrentCell.Y;
// OnRowValidating returns true when the row validation was cancelled.
if (OnRowValidating(ref dataGridViewCurrentCell, columnIndex, rowIndex))
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
OnRowEnter(ref dataGridViewCurrentCell, columnIndex, rowIndex, true /*canCreateNewRow*/, true /*validationFailureOccurred*/);
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
OnCellEnter(ref dataGridViewCurrentCell, columnIndex, rowIndex);
return false;
}
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
OnRowValidated(ref dataGridViewCurrentCell, columnIndex, rowIndex);
}
return true;
}
private bool CommitEditForOperation(int columnIndex, int rowIndex, bool forCurrentCellChange)
{
if (forCurrentCellChange)
{
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.CurrentCellChange,
DataGridViewValidateCellInternal.Always /*validateCell*/,
true /*fireCellLeave*/,
true /*fireCellEnter*/,
this.ptCurrentCell.Y != rowIndex /*fireRowLeave*/,
this.ptCurrentCell.Y != rowIndex /*fireRowEnter*/,
false /*fireLeave*/,
this.EditMode != DataGridViewEditMode.EditOnEnter /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell unused here*/))
{
return false;
}
if (this.ptCurrentCell.Y != rowIndex && this.ptCurrentCell.Y != -1)
{
DataGridViewCell dataGridViewCellTmp = null;
int columnIndexTmp = this.ptCurrentCell.X;
int rowIndexTmp = this.ptCurrentCell.Y;
if (OnRowValidating(ref dataGridViewCellTmp, columnIndexTmp, rowIndexTmp))
{
// Row validation was cancelled
if (IsInnerCellOutOfBounds(columnIndexTmp, rowIndexTmp))
{
return false;
}
OnRowEnter(ref dataGridViewCellTmp, columnIndexTmp, rowIndexTmp, true /*canCreateNewRow*/, true /*validationFailureOccurred*/);
if (IsInnerCellOutOfBounds(columnIndexTmp, rowIndexTmp))
{
return false;
}
OnCellEnter(ref dataGridViewCellTmp, columnIndexTmp, rowIndexTmp);
if (IsInnerCellOutOfBounds(columnIndexTmp, rowIndexTmp))
{
return false;
}
// Re-enter editing mode if needed
if (this.Focused &&
(!this.IsCurrentCellInEditMode && (this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null))))
{
BeginEditInternal(true /*selectAll*/);
}
return false;
}
if (IsInnerCellOutOfBounds(columnIndexTmp, rowIndexTmp))
{
return false;
}
OnRowValidated(ref dataGridViewCellTmp, columnIndexTmp, rowIndexTmp);
}
}
else
{
if (!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
false /*forCurrentCellChange*/,
this.ptCurrentCell.Y != rowIndex /*forCurrentRowChange*/))
{
return false;
}
}
// Row validation was not cancelled, but operation needs to be re-evaluated.
Debug.Assert(columnIndex < this.Columns.Count);
if (IsColumnOutOfBounds(columnIndex))
{
return false;
}
if (rowIndex >= this.Rows.Count)
{
// CurrentCell was reset because the commit deleted row(s).
// Since the user wants to change the current cell, we don't
// want to end up with no CurrentCell. We pick the last visible
// row in the grid which may be the 'new row'.
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
if (forCurrentCellChange &&
this.ptCurrentCell.X == -1 &&
lastVisibleRowIndex != -1)
{
bool success = SetAndSelectCurrentCellAddress(columnIndex, lastVisibleRowIndex, true, false, false, false /*clearSelection*/, false /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
// Interrupt operation because it has become invalid.
return false;
}
if (rowIndex > -1 && (this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) == 0)
{
// Interrupt operation because target row has become invisible.
return false;
}
return true;
}
internal void CompleteCellsCollection(DataGridViewRow dataGridViewRow)
{
Debug.Assert(dataGridViewRow != null);
int cellsInCollection = dataGridViewRow.Cells.Count;
if (this.Columns.Count > cellsInCollection)
{
int cellCount = 0;
DataGridViewCell[] cells = new DataGridViewCell[this.Columns.Count - cellsInCollection];
for (int columnIndex = cellsInCollection; columnIndex < this.Columns.Count; columnIndex++)
{
if (this.Columns[columnIndex].CellTemplate == null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_AColumnHasNoCellTemplate));
}
DataGridViewCell dgvcNew = (DataGridViewCell) this.Columns[columnIndex].CellTemplate.Clone();
cells[cellCount] = dgvcNew;
cellCount ++;
}
dataGridViewRow.Cells.AddRange(cells);
}
}
/// <devdoc>
/// Determines which column is the first visible scrolling
/// column given the object's horizontalOffset.
/// </devdoc>
private int ComputeFirstVisibleScrollingColumn()
{
if (this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen) >= this.layout.Data.Width)
{
// Not enough room for scrolling columns.
this.negOffset = 0;
return -1;
}
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
if (this.horizontalOffset == 0)
{
this.negOffset = 0;
return (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
}
int cx = 0;
while (dataGridViewColumn != null)
{
cx += dataGridViewColumn.Thickness;
if (cx > this.horizontalOffset)
{
break;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
if (dataGridViewColumn == null)
{
Debug.Assert(cx <= this.horizontalOffset);
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
if (dataGridViewColumn == null)
{
this.negOffset = 0;
return -1;
}
else
{
if (this.negOffset != this.horizontalOffset)
{
this.negOffset = 0;
}
return dataGridViewColumn.Index;
}
}
else
{
this.negOffset = dataGridViewColumn.Thickness - (cx - this.horizontalOffset);
return dataGridViewColumn.Index;
}
}
private int ComputeHeightOfFittingTrailingScrollingRows(int totalVisibleFrozenHeight)
{
//
int displayHeight = this.layout.Data.Height - totalVisibleFrozenHeight;
int rowHeight = 0, rowHeights = 0;
int indexTmp = this.Rows.Count;
if (indexTmp == 0 || displayHeight <= 0)
{
return 0;
}
else
{
indexTmp--;
}
DataGridViewElementStates rowState = this.Rows.GetRowState(indexTmp);
if ((rowState & DataGridViewElementStates.Frozen) != 0)
{
return 0;
}
if ((rowState & DataGridViewElementStates.Visible) == 0)
{
indexTmp = this.Rows.GetPreviousRow(indexTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
}
if (indexTmp != -1)
{
rowHeight = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
if (rowHeight > displayHeight)
{
return rowHeight;
}
}
while (indexTmp != -1 && rowHeights + rowHeight <= displayHeight)
{
rowHeights += rowHeight;
indexTmp = this.Rows.GetPreviousRow(indexTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
if (indexTmp != -1)
{
rowHeight = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
}
}
return rowHeights;
}
private int ComputeHeightOfScrolledOffRows()
{
//
int height = 0;
if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0)
{
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
if (rowIndex != -1)
{
while (rowIndex != this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
Debug.Assert(rowIndex < this.displayedBandsInfo.FirstDisplayedScrollingRow);
height += this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
}
}
return height;
}
private int ComputeHeightOfTrailingScrollingRows()
{
if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0)
{
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
return this.Rows.GetRowsHeight(DataGridViewElementStates.Visible, this.displayedBandsInfo.FirstDisplayedScrollingRow, lastVisibleRowIndex) +
this.Rows.SharedRow(lastVisibleRowIndex).GetHeight(lastVisibleRowIndex);
}
return 0;
}
private bool ComputeLayout()
{
ClearRegionCache();
LayoutData newLayout = new LayoutData(this.layout);
Rectangle oldResizeRect = this.layout.ResizeBoxRect;
// Inside region
if (this.normalClientRectangle.Width > 0 || this.normalClientRectangle.Height > 0)
{
newLayout.Inside = this.normalClientRectangle;
}
else
{
newLayout.Inside = this.ClientRectangle;
}
Rectangle inside = newLayout.Inside;
int borderWidth = this.BorderWidth;
inside.Inflate(-borderWidth, -borderWidth);
if (inside.Height < 0)
{
inside.Height = 0;
}
if (inside.Width < 0)
{
inside.Width = 0;
}
Rectangle insideLeft = inside;
// Headers
if (this.layout.ColumnHeadersVisible)
{
Rectangle colHeaders = insideLeft;
colHeaders.Height = Math.Min(this.columnHeadersHeight, colHeaders.Height);
insideLeft.Y += colHeaders.Height;
insideLeft.Height -= colHeaders.Height;
Debug.Assert(insideLeft.Height >= 0);
newLayout.ColumnHeaders = colHeaders;
}
else
{
newLayout.ColumnHeaders = Rectangle.Empty;
}
if (this.layout.RowHeadersVisible)
{
Rectangle rowHeaders = insideLeft;
rowHeaders.Width = Math.Min(this.rowHeadersWidth, rowHeaders.Width);
if (this.RightToLeftInternal)
{
rowHeaders.X += insideLeft.Width - rowHeaders.Width;
}
else
{
insideLeft.X += rowHeaders.Width;
}
insideLeft.Width -= rowHeaders.Width;
Debug.Assert(insideLeft.Width >= 0);
newLayout.RowHeaders = rowHeaders;
if (this.layout.ColumnHeadersVisible)
{
Rectangle topLeft;
Rectangle colHeaders = newLayout.ColumnHeaders;
topLeft = colHeaders;
topLeft.Width = Math.Min(this.rowHeadersWidth, topLeft.Width);
colHeaders.Width -= topLeft.Width;
if (this.RightToLeftInternal)
{
topLeft.X += insideLeft.Width;
}
else
{
colHeaders.X += topLeft.Width;
}
Debug.Assert(colHeaders.Width >= 0);
newLayout.TopLeftHeader = topLeft;
newLayout.ColumnHeaders = colHeaders;
}
else
{
newLayout.TopLeftHeader = Rectangle.Empty;
}
}
else
{
newLayout.RowHeaders = Rectangle.Empty;
newLayout.TopLeftHeader = Rectangle.Empty;
}
// Adjust insideLeft in case static top / left edge needs to be painted
if (this.SingleVerticalBorderAdded)
{
if (!this.RightToLeftInternal)
{
insideLeft.X++;
}
if (insideLeft.Width > 0)
{
insideLeft.Width--;
}
}
if (this.SingleHorizontalBorderAdded)
{
insideLeft.Y++;
if (insideLeft.Height > 0)
{
insideLeft.Height--;
}
}
// Data region
newLayout.Data = insideLeft;
newLayout.Inside = inside;
Debug.Assert(newLayout.Data.X >= 0);
Debug.Assert(newLayout.Data.Y >= 0);
Debug.Assert(newLayout.Data.Width >= 0);
Debug.Assert(newLayout.Data.Height >= 0);
this.layout = newLayout;
this.layout.dirty = false;
bool columnsAdjusted = AdjustFillingColumns();
this.layout = newLayout;
Debug.Assert(!this.layout.dirty);
LayoutScrollBars();
// if the user shrank the grid client area, then OnResize invalidated the old
// resize area. however, we need to invalidate the left upper corner in the new ResizeArea
// note that we can't take the Invalidate call from the OnResize method, because if the
// user enlarges the form then the old area will not be invalidated.
//
if (!oldResizeRect.Equals(this.layout.ResizeBoxRect) && !this.layout.ResizeBoxRect.IsEmpty)
{
Invalidate(this.layout.ResizeBoxRect);
}
return columnsAdjusted;
}
private void ComputeLayoutShortcut(bool computeVisibleRows)
{
// Called instead of ComputeLayout when a row is added, inserted or deleted beyond the limits of
// the layout.Data area.
// this.layout is unchanged - only the potential vertical scrollbar is affected.
if (computeVisibleRows)
{
ComputeVisibleRows();
}
#if DEBUG
else
{
int oldNumTotallyVisibleFrozenRows = this.displayedBandsInfo.NumTotallyDisplayedFrozenRows;
int oldNumVisibleScrollingRows = this.displayedBandsInfo.NumDisplayedScrollingRows;
int oldNumTotallyVisibleScrollingRows = this.displayedBandsInfo.NumTotallyDisplayedScrollingRows;
int oldFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
ComputeVisibleRows();
Debug.Assert(oldNumTotallyVisibleFrozenRows == this.displayedBandsInfo.NumTotallyDisplayedFrozenRows);
Debug.Assert(oldNumVisibleScrollingRows == this.displayedBandsInfo.NumDisplayedScrollingRows);
Debug.Assert(oldNumTotallyVisibleScrollingRows == this.displayedBandsInfo.NumTotallyDisplayedScrollingRows);
Debug.Assert(oldFirstVisibleScrollingRow == this.displayedBandsInfo.FirstDisplayedScrollingRow);
}
#endif
#if DEBUG
int newFirstVisibleScrollingCol = ComputeFirstVisibleScrollingColumn();
Debug.Assert(newFirstVisibleScrollingCol == this.displayedBandsInfo.FirstDisplayedScrollingCol);
int oldLastTotallyVisibleScrollingCol = this.displayedBandsInfo.LastTotallyDisplayedScrollingCol;
int oldFirstVisibleScrollingCol = this.displayedBandsInfo.FirstDisplayedScrollingCol;
ComputeVisibleColumns();
Debug.Assert(oldLastTotallyVisibleScrollingCol == this.displayedBandsInfo.LastTotallyDisplayedScrollingCol);
Debug.Assert(oldFirstVisibleScrollingCol == this.displayedBandsInfo.FirstDisplayedScrollingCol);
#endif
if (this.vertScrollBar.Enabled)
{
int totalVisibleHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible);
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
int oldVertScrollBarValue = this.vertScrollBar.Value;
int oldThumbHeight = Math.Max(((this.vertScrollBar.Height - 2*SystemInformation.VerticalScrollBarArrowHeight) * this.vertScrollBar.LargeChange) / this.vertScrollBar.Maximum, 8);
this.vertScrollBar.Maximum = totalVisibleHeight - totalVisibleFrozenHeight;
Debug.Assert(this.vertScrollBar.Maximum > 0);
this.vertScrollBar.Value = ComputeHeightOfScrolledOffRows();
this.vertScrollBar.LargeChange = this.layout.Data.Height - totalVisibleFrozenHeight;
this.verticalOffset = this.vertScrollBar.Value;
if (this.vertScrollBar.Visible &&
(oldVertScrollBarValue != this.verticalOffset ||
oldThumbHeight != Math.Max(((this.vertScrollBar.Height - 2*SystemInformation.VerticalScrollBarArrowHeight) * this.vertScrollBar.LargeChange) / this.vertScrollBar.Maximum, 8)))
{
// Only update the vertical scroll bar is the thumb moved or resized.
this.vertScrollBar.Invalidate();
}
Debug.Assert(this.verticalOffset == this.vertScrollBar.Value);
}
}
/* Unused for now
private int ComputeScrolledOffRowCount(int scrolledOffRowsHeight)
{
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
if (rowIndex == -1)
{
// No scrolling rows
return 0;
}
else
{
int height = 0;
int rowCount = 0;
while (rowIndex != -1 && height < scrolledOffRowsHeight)
{
height += this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
if (height <= scrolledOffRowsHeight)
{
rowCount++;
}
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
return rowCount;
}
}
*/
private void ComputeVisibleColumns()
{
DataGridViewColumn dataGridViewColumn = null;
int numVisibleScrollingCols = 0, visibleScrollingColumnsTmp = 0;
int displayWidth = this.layout.Data.Width, cx = 0;
int numDisplayedFrozenCols = 0, firstDisplayedFrozenCol = -1, lastDisplayedFrozenCol = -1;
int firstDisplayedScrollingCol = this.displayedBandsInfo.FirstDisplayedScrollingCol;
// the same problem with negative numbers:
// if the width passed in is negative, then return 0
if (displayWidth <= 0 || this.Columns.GetColumnCount(DataGridViewElementStates.Visible) == 0)
{
this.displayedBandsInfo.FirstDisplayedFrozenCol = -1;
this.displayedBandsInfo.NumDisplayedFrozenCols = 0;
this.displayedBandsInfo.FirstDisplayedScrollingCol = -1;
this.displayedBandsInfo.NumDisplayedScrollingCols = 0;
this.displayedBandsInfo.LastDisplayedFrozenCol = -1;
this.displayedBandsInfo.LastTotallyDisplayedScrollingCol = -1;
return;
}
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.None);
while (dataGridViewColumn != null)
{
if (!dataGridViewColumn.Frozen && dataGridViewColumn.Visible)
{
break;
}
if (dataGridViewColumn.Visible)
{
if (firstDisplayedFrozenCol == -1)
{
firstDisplayedFrozenCol = dataGridViewColumn.Index;
}
cx += dataGridViewColumn.Width;
numDisplayedFrozenCols++;
lastDisplayedFrozenCol = dataGridViewColumn.Index;
if (cx >= displayWidth)
{
break;
}
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.None, DataGridViewElementStates.None);
}
Debug.Assert(cx <= this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen));
if (cx < displayWidth && firstDisplayedScrollingCol >= 0)
{
dataGridViewColumn = this.Columns[firstDisplayedScrollingCol];
if (dataGridViewColumn.Frozen)
{
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
this.negOffset = 0;
if (dataGridViewColumn == null)
{
this.displayedBandsInfo.FirstDisplayedFrozenCol = firstDisplayedFrozenCol;
this.displayedBandsInfo.LastDisplayedFrozenCol = lastDisplayedFrozenCol;
this.displayedBandsInfo.NumDisplayedFrozenCols = numDisplayedFrozenCols;
this.displayedBandsInfo.FirstDisplayedScrollingCol = this.displayedBandsInfo.LastTotallyDisplayedScrollingCol = -1;
this.displayedBandsInfo.NumDisplayedScrollingCols = 0;
return;
}
else
{
firstDisplayedScrollingCol = dataGridViewColumn.Index;
}
}
cx -= this.negOffset;
while (cx < displayWidth && dataGridViewColumn != null)
{
cx += dataGridViewColumn.Thickness;
visibleScrollingColumnsTmp++;
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
numVisibleScrollingCols = visibleScrollingColumnsTmp;
// if we inflate the data area then we paint columns to the left of firstDisplayedScrollingCol
if (cx < displayWidth)
{
bool invalidate = false;
Debug.Assert(firstDisplayedScrollingCol >= 0);
//first minimize value of this.negOffset
if (this.negOffset > 0)
{
invalidate = true;
if (displayWidth - cx > this.negOffset)
{
cx += this.negOffset;
this.horizontalOffset -= this.negOffset;
this.negOffset = 0;
}
else
{
this.horizontalOffset -= displayWidth - cx;
this.negOffset -= displayWidth - cx;
cx = displayWidth;
}
}
// second try to scroll entire columns
if (cx < displayWidth && this.horizontalOffset > 0)
{
Debug.Assert(this.negOffset == 0);
dataGridViewColumn = this.Columns.GetPreviousColumn((this.Columns[firstDisplayedScrollingCol]),
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
while (dataGridViewColumn != null && cx + dataGridViewColumn.Thickness <= displayWidth)
{
cx += dataGridViewColumn.Thickness;
visibleScrollingColumnsTmp++;
invalidate = true;
firstDisplayedScrollingCol = dataGridViewColumn.Index;
this.horizontalOffset -= dataGridViewColumn.Thickness;
dataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
}
}
// third try to partially scroll in first scrolled off column
if (cx < displayWidth && this.horizontalOffset > 0 && firstDisplayedScrollingCol != 0)
{
Debug.Assert(this.negOffset == 0);
dataGridViewColumn = this.Columns.GetPreviousColumn((this.Columns[firstDisplayedScrollingCol]),
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(dataGridViewColumn.Thickness > displayWidth - cx);
firstDisplayedScrollingCol = dataGridViewColumn.Index;
this.negOffset = dataGridViewColumn.Thickness - displayWidth + cx;
this.horizontalOffset -= displayWidth - cx;
visibleScrollingColumnsTmp++;
invalidate = true;
cx = displayWidth;
Debug.Assert(this.negOffset == GetNegOffsetFromHorizontalOffset(this.horizontalOffset));
}
// update the number of visible columns to the new reality
Debug.Assert(numVisibleScrollingCols <= visibleScrollingColumnsTmp, "the number of displayed columns can only grow");
numVisibleScrollingCols = visibleScrollingColumnsTmp;
if (invalidate)
{
InvalidateData();
Invalidate(this.layout.ColumnHeaders);
}
}
int jumpFromFirstVisibleScrollingCol = numVisibleScrollingCols - 1;
if (cx > displayWidth)
{
jumpFromFirstVisibleScrollingCol--;
}
Debug.Assert(jumpFromFirstVisibleScrollingCol >= -1);
if (jumpFromFirstVisibleScrollingCol < 0)
{
this.displayedBandsInfo.LastTotallyDisplayedScrollingCol = -1; // no totally visible scrolling column at all
}
else
{
Debug.Assert(firstDisplayedScrollingCol >= 0);
dataGridViewColumn = this.Columns[firstDisplayedScrollingCol];
for (int jump = 0; jump < jumpFromFirstVisibleScrollingCol; jump++)
{
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
}
this.displayedBandsInfo.LastTotallyDisplayedScrollingCol = dataGridViewColumn.Index;
}
}
else
{
this.displayedBandsInfo.LastTotallyDisplayedScrollingCol = -1;
}
this.displayedBandsInfo.FirstDisplayedFrozenCol = firstDisplayedFrozenCol;
this.displayedBandsInfo.LastDisplayedFrozenCol = lastDisplayedFrozenCol;
this.displayedBandsInfo.NumDisplayedFrozenCols = numDisplayedFrozenCols;
this.displayedBandsInfo.FirstDisplayedScrollingCol = firstDisplayedScrollingCol;
this.displayedBandsInfo.NumDisplayedScrollingCols = numVisibleScrollingCols;
Debug.Assert((this.displayedBandsInfo.NumDisplayedScrollingCols > 0 && this.displayedBandsInfo.FirstDisplayedScrollingCol != -1) ||
(this.displayedBandsInfo.NumDisplayedScrollingCols == 0 && this.displayedBandsInfo.FirstDisplayedScrollingCol == -1));
}
private void ComputeVisibleRows()
{
int firstDisplayedFrozenRow = -1;
int firstDisplayedScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
int lastDisplayedFrozenRow = -1, lastDisplayedScrollingRow = -1;
int numTotallyDisplayedFrozenRows = 0;
int displayHeight = this.layout.Data.Height;
int cy = 0;
int visibleScrollingRows = 0;
int nRows = this.Rows.Count;
int rowIndex;
// when minimizing the dataGridView window, we will get negative values for the
// layout.Data.Width and layout.Data.Height ( is this a bug or not? if layout.Data.Height == 0 in that case,
// the old code would have worked )
//
// if this is the case, set numTotallyDisplayedFrozenRows = numDisplayedScrollingRows = numTotallyDisplayedScrollingRows = 0;
//
if (displayHeight <= 0 || nRows == 0)
{
this.displayedBandsInfo.NumDisplayedFrozenRows = this.displayedBandsInfo.NumTotallyDisplayedFrozenRows =
this.displayedBandsInfo.NumDisplayedScrollingRows = this.displayedBandsInfo.NumTotallyDisplayedScrollingRows = 0;
this.displayedBandsInfo.FirstDisplayedFrozenRow = this.displayedBandsInfo.FirstDisplayedScrollingRow =
this.displayedBandsInfo.LastDisplayedFrozenRow = this.displayedBandsInfo.LastDisplayedScrollingRow = -1;
return;
}
for (rowIndex = 0; rowIndex < nRows; rowIndex++)
{
Debug.Assert(cy < displayHeight);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if ((rowState & DataGridViewElementStates.Frozen) == 0 &&
(rowState & DataGridViewElementStates.Visible) != 0)
{
break;
}
if ((rowState & DataGridViewElementStates.Visible) != 0)
{
cy += this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
if (firstDisplayedFrozenRow == -1)
{
firstDisplayedFrozenRow = rowIndex;
}
lastDisplayedFrozenRow = rowIndex;
if (cy <= displayHeight)
{
numTotallyDisplayedFrozenRows++;
}
if (cy >= displayHeight)
{
break;
}
}
}
if (cy > displayHeight)
{
this.displayedBandsInfo.NumDisplayedFrozenRows = numTotallyDisplayedFrozenRows + 1;
}
else
{
this.displayedBandsInfo.NumDisplayedFrozenRows = numTotallyDisplayedFrozenRows;
}
// loop exited when:
// - all rows are frozen and fit in displayHeight: rowIndex == nRows, cy <= displayHeight
// - rowIndex is not frozen: rowIndex < nRows, cy <= displayHeight
// - there are more frozen rows than can fit in displayHeight: rowIndex <= nRows, cy > displayHeight
if (cy < displayHeight && rowIndex < nRows)
{
if (firstDisplayedScrollingRow == -1)
{
firstDisplayedScrollingRow = rowIndex;
}
while (firstDisplayedScrollingRow < nRows &&
(
(this.Rows.GetRowState(firstDisplayedScrollingRow) & DataGridViewElementStates.Frozen) != 0 ||
(this.Rows.GetRowState(firstDisplayedScrollingRow) & DataGridViewElementStates.Visible) == 0
)
)
{
firstDisplayedScrollingRow++;
}
for (int i = firstDisplayedScrollingRow; i < nRows; i++)
{
if ((this.Rows.GetRowState(i) & DataGridViewElementStates.Visible) != 0)
{
cy += this.Rows.SharedRow(i).GetHeight(i);
visibleScrollingRows++;
lastDisplayedScrollingRow = i;
}
if (cy >= displayHeight)
{
break;
}
}
if (cy < displayHeight)
{
for (int i = firstDisplayedScrollingRow - 1; i >= numTotallyDisplayedFrozenRows; i--)
{
if ((this.Rows.GetRowState(i) & (DataGridViewElementStates.Frozen | DataGridViewElementStates.Visible)) == DataGridViewElementStates.Visible)
{
int height = this.Rows.SharedRow(i).GetHeight(i);
if (cy + height > displayHeight)
{
break;
}
cy += height;
firstDisplayedScrollingRow = i;
visibleScrollingRows++;
lastDisplayedScrollingRow = i;
}
}
}
this.displayedBandsInfo.NumDisplayedScrollingRows = visibleScrollingRows;
if (cy > displayHeight)
{
this.displayedBandsInfo.NumTotallyDisplayedScrollingRows = visibleScrollingRows - 1;
}
else
{
this.displayedBandsInfo.NumTotallyDisplayedScrollingRows = visibleScrollingRows;
}
if (visibleScrollingRows == 0)
{
firstDisplayedScrollingRow = -1;
Debug.Assert(lastDisplayedScrollingRow == -1);
}
}
else
{
this.displayedBandsInfo.NumDisplayedScrollingRows = this.displayedBandsInfo.NumTotallyDisplayedScrollingRows = 0;
firstDisplayedScrollingRow = -1;
}
Debug.Assert(firstDisplayedFrozenRow < nRows, "firstDisplayedFrozenRow larger than number of rows");
Debug.Assert(lastDisplayedFrozenRow < nRows, "lastDisplayedFrozenRow larger than number of rows");
Debug.Assert(lastDisplayedScrollingRow < nRows, "lastDisplayedScrollingRow larger than number of rows");
this.displayedBandsInfo.FirstDisplayedFrozenRow = firstDisplayedFrozenRow;
this.displayedBandsInfo.FirstDisplayedScrollingRow = firstDisplayedScrollingRow;
this.displayedBandsInfo.NumTotallyDisplayedFrozenRows = numTotallyDisplayedFrozenRows;
this.displayedBandsInfo.LastDisplayedFrozenRow = lastDisplayedFrozenRow;
this.displayedBandsInfo.LastDisplayedScrollingRow = lastDisplayedScrollingRow;
Debug.Assert(this.displayedBandsInfo.NumTotallyDisplayedFrozenRows >= 0, "the number of visible frozen rows can't be negative");
Debug.Assert(this.displayedBandsInfo.NumDisplayedScrollingRows >= 0, "the number of visible scrolling rows can't be negative");
Debug.Assert(this.displayedBandsInfo.NumTotallyDisplayedScrollingRows >= 0, "the number of totally visible scrolling rows can't be negative");
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow < nRows, "firstDisplayedScrollingRow larger than number of rows");
}
private Point ConvertCellToGridCoord(int columnIndex, int rowIndex, int x, int y)
{
int columnX, rowY;
if (columnIndex > -1)
{
columnX = GetColumnXFromIndex(columnIndex);
if (this.RightToLeftInternal)
{
columnX -= this.Columns[columnIndex].Width;
}
}
else
{
if (this.RightToLeftInternal)
{
columnX = this.layout.RowHeaders.Left - 1;
}
else
{
columnX = this.layout.RowHeaders.Left;
}
}
if (rowIndex > -1)
{
rowY = GetRowYFromIndex(rowIndex);
}
else
{
rowY = this.layout.ColumnHeaders.Top;
}
return new Point(columnX + x, rowY + y);
}
private void CorrectColumnDisplayIndexesAfterDeletion(DataGridViewColumn dataGridViewColumn)
{
// Column indexes have already been adjusted.
// This column has already been detached and has retained its old Index and DisplayIndex
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(dataGridViewColumn.DataGridView == null);
Debug.Assert(dataGridViewColumn.Index >= 0);
Debug.Assert(dataGridViewColumn.DisplayIndex >= 0);
try
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments] = true;
// All remaining columns with a DisplayIndex greater than dataGridViewColumn.DisplayIndex need to be decremented
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp.DisplayIndex > dataGridViewColumn.DisplayIndex)
{
dataGridViewColumnTmp.DisplayIndexInternal = dataGridViewColumnTmp.DisplayIndex - 1;
dataGridViewColumnTmp.DisplayIndexHasChanged = true; // OnColumnDisplayIndexChanged needs to be raised later on
}
}
#if DEBUG
Debug.Assert(this.Columns.VerifyColumnDisplayIndexes());
#endif
// Now raise all the OnColumnDisplayIndexChanged events
FlushDisplayIndexChanged(true /*raiseEvent*/);
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments] = false;
FlushDisplayIndexChanged(false /*raiseEvent*/);
}
}
private void CorrectColumnDisplayIndexesAfterInsertion(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(dataGridViewColumn.DataGridView == this);
// dataGridViewColumn.DisplayIndex has been set already.
Debug.Assert(dataGridViewColumn.DisplayIndex >= 0);
Debug.Assert(dataGridViewColumn.DisplayIndex < this.Columns.Count);
try
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments] = true;
// All other columns with a DisplayIndex equal or greater than dataGridViewColumn.DisplayIndex need to be incremented
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumnTmp != dataGridViewColumn && dataGridViewColumnTmp.DisplayIndex >= dataGridViewColumn.DisplayIndex)
{
dataGridViewColumnTmp.DisplayIndexInternal = dataGridViewColumnTmp.DisplayIndex + 1;
dataGridViewColumnTmp.DisplayIndexHasChanged = true; // OnColumnDisplayIndexChanged needs to be raised later on
}
}
#if DEBUG
Debug.Assert(this.Columns.VerifyColumnDisplayIndexes());
#endif
// Now raise all the OnColumnDisplayIndexChanged events
FlushDisplayIndexChanged(true /*raiseEvent*/);
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments] = false;
FlushDisplayIndexChanged(false /*raiseEvent*/);
}
}
private void CorrectColumnFrozenState(DataGridViewColumn dataGridViewColumn, int anticipatedColumnIndex)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(anticipatedColumnIndex >= 0 && anticipatedColumnIndex <= this.Columns.Count);
int anticipatedColumnDisplayIndex;
if (dataGridViewColumn.DisplayIndex == -1 || dataGridViewColumn.DisplayIndex > this.Columns.Count)
{
anticipatedColumnDisplayIndex = anticipatedColumnIndex; // By default, we pick the Index as the DisplayIndex.
}
else
{
Debug.Assert(dataGridViewColumn.DisplayIndex >= 0 && dataGridViewColumn.DisplayIndex <= this.Columns.Count);
anticipatedColumnDisplayIndex = dataGridViewColumn.DisplayIndex; // The specified DisplayIndex is just fine.
}
DataGridViewColumn dataGridViewColumnPrev;
int displayIndex = anticipatedColumnDisplayIndex-1;
do
{
dataGridViewColumnPrev = this.Columns.GetColumnAtDisplayIndex(displayIndex);
displayIndex--;
}
while (displayIndex >= 0 && (dataGridViewColumnPrev == null || !dataGridViewColumnPrev.Visible));
if (dataGridViewColumnPrev != null && !dataGridViewColumnPrev.Frozen && dataGridViewColumn.Frozen)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddFrozenColumn));
}
else
{
DataGridViewColumn dataGridViewColumnNext;
displayIndex = anticipatedColumnDisplayIndex;
do
{
dataGridViewColumnNext = this.Columns.GetColumnAtDisplayIndex(displayIndex);
displayIndex++;
}
while (displayIndex < this.Columns.Count && (dataGridViewColumnNext == null || !dataGridViewColumnNext.Visible));
if (dataGridViewColumnNext != null && dataGridViewColumnNext.Frozen && !dataGridViewColumn.Frozen)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddNonFrozenColumn));
}
}
}
private void CorrectColumnFrozenStates(DataGridViewColumn[] dataGridViewColumns)
{
DataGridView dataGridViewTmp = new DataGridView();
DataGridViewColumn dataGridViewColumnClone;
foreach (DataGridViewColumn dataGridViewColumn in this.Columns)
{
dataGridViewColumnClone = (DataGridViewColumn) dataGridViewColumn.Clone();
// DataGridViewColumn.Clone does not replicate the DisplayIndex value.
dataGridViewColumnClone.DisplayIndex = dataGridViewColumn.DisplayIndex;
dataGridViewTmp.Columns.Add(dataGridViewColumnClone);
}
foreach (DataGridViewColumn dataGridViewColumn in dataGridViewColumns)
{
dataGridViewColumnClone = (DataGridViewColumn) dataGridViewColumn.Clone();
dataGridViewColumnClone.DisplayIndex = dataGridViewColumn.DisplayIndex;
dataGridViewTmp.Columns.Add(dataGridViewColumnClone);
}
}
private void CorrectColumnFrozenStates(DataGridViewColumn dataGridViewColumn, bool frozenStateChanging)
{
Debug.Assert(dataGridViewColumn != null);
DataGridViewColumn dataGridViewColumnTmp;
if ((dataGridViewColumn.Frozen && !frozenStateChanging) ||
(!dataGridViewColumn.Frozen && frozenStateChanging))
{
// make sure the previous visible columns are frozen as well
dataGridViewColumnTmp = this.Columns.GetPreviousColumn(dataGridViewColumn,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen,
DataGridViewElementStates.None);
if (dataGridViewColumnTmp == null)
{
DataGridViewColumn dataGridViewColumnFirst = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
if (dataGridViewColumnFirst != dataGridViewColumn)
{
dataGridViewColumnTmp = dataGridViewColumnFirst;
}
}
while (dataGridViewColumnTmp != null && this.Columns.DisplayInOrder(dataGridViewColumnTmp.Index, dataGridViewColumn.Index))
{
dataGridViewColumnTmp.Frozen = true;
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
}
}
else
{
// make sure the next visible columns are not frozen
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
if (dataGridViewColumnTmp == null)
{
DataGridViewColumn dataGridViewColumnLast = dataGridViewColumn;
do
{
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnLast,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumnTmp != null)
{
dataGridViewColumnLast = dataGridViewColumnTmp;
}
}
while (dataGridViewColumnTmp != null);
if (dataGridViewColumnLast != dataGridViewColumn)
{
dataGridViewColumnTmp = dataGridViewColumnLast;
}
}
while (dataGridViewColumnTmp != null && this.Columns.DisplayInOrder(dataGridViewColumn.Index, dataGridViewColumnTmp.Index))
{
dataGridViewColumnTmp.Frozen = false;
dataGridViewColumnTmp = this.Columns.GetPreviousColumn(dataGridViewColumnTmp,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen,
DataGridViewElementStates.None);
}
}
}
private void CorrectColumnFrozenStatesForMove(DataGridViewColumn dataGridViewColumn, int newDisplayIndex)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(newDisplayIndex != dataGridViewColumn.DisplayIndex);
Debug.Assert(!this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments]);
// No check necessary when:
// - column is invisible.
// - DisplayIndex decreases and column is frozen.
// - DisplayIndex increases and column is unfrozen.
if (!dataGridViewColumn.Visible ||
(newDisplayIndex < dataGridViewColumn.DisplayIndex && dataGridViewColumn.Frozen) ||
(newDisplayIndex > dataGridViewColumn.DisplayIndex && !dataGridViewColumn.Frozen))
{
return;
}
int colCount = this.Columns.Count, displayIndex;
if (newDisplayIndex < dataGridViewColumn.DisplayIndex)
{
// DisplayIndex decreases.
// Throw an exception if the visible unfrozen column is placed before a frozen column
// Get the closest visible column placed after the displaced column
DataGridViewColumn dataGridViewColumnNext;
displayIndex = newDisplayIndex;
do
{
dataGridViewColumnNext = this.Columns.GetColumnAtDisplayIndex(displayIndex);
displayIndex++;
}
while (displayIndex < colCount && (dataGridViewColumnNext == null || dataGridViewColumnNext == dataGridViewColumn || !dataGridViewColumnNext.Visible));
if (dataGridViewColumnNext != null && dataGridViewColumnNext.Frozen)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotMoveNonFrozenColumn));
}
}
else
{
// DisplayIndex increases.
// Throw an exception if the visible frozen column is placed after a non-frozen column
// Get the closest visible column placed before the displaced column
DataGridViewColumn dataGridViewColumnPrev;
displayIndex = newDisplayIndex;
do
{
dataGridViewColumnPrev = this.Columns.GetColumnAtDisplayIndex(displayIndex);
displayIndex--;
}
while (displayIndex >= 0 && (dataGridViewColumnPrev == null || !dataGridViewColumnPrev.Visible));
if (dataGridViewColumnPrev != null && !dataGridViewColumnPrev.Frozen)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotMoveFrozenColumn));
}
}
}
private void CorrectColumnIndexesAfterDeletion(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
for (int columnIndex = dataGridViewColumn.Index; columnIndex < this.Columns.Count; columnIndex++)
{
this.Columns[columnIndex].IndexInternal = this.Columns[columnIndex].Index - 1;
Debug.Assert(this.Columns[columnIndex].Index == columnIndex);
}
}
private void CorrectColumnIndexesAfterInsertion(DataGridViewColumn dataGridViewColumn, int insertionCount)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(insertionCount > 0);
for (int columnIndex = dataGridViewColumn.Index + insertionCount; columnIndex < this.Columns.Count; columnIndex++)
{
this.Columns[columnIndex].IndexInternal = columnIndex;
}
}
private void CorrectFocus(bool onlyIfGridHasFocus)
{
if ((!onlyIfGridHasFocus || this.Focused) && this.editingControl != null)
{
Debug.Assert(this.CurrentCellInternal != null);
//Debug.Assert(this.editingControl.CanFocus);
this.editingControl.FocusInternal();
}
}
private void CorrectRowFrozenState(DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, int anticipatedRowIndex)
{
Debug.Assert(dataGridViewRow != null);
Debug.Assert(anticipatedRowIndex >= 0 && anticipatedRowIndex <= this.Rows.Count);
int previousRowIndex = this.Rows.GetPreviousRow(anticipatedRowIndex,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (previousRowIndex != -1 &&
(this.Rows.GetRowState(previousRowIndex) & DataGridViewElementStates.Frozen) == 0 &&
(rowState & DataGridViewElementStates.Frozen) != 0)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddFrozenRow));
}
else
{
int nextRowIndex = this.Rows.GetNextRow((previousRowIndex == -1) ? anticipatedRowIndex - 1 : previousRowIndex,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (nextRowIndex != -1 &&
(this.Rows.GetRowState(nextRowIndex) & DataGridViewElementStates.Frozen) != 0 &&
(rowState & DataGridViewElementStates.Frozen) == 0)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddNonFrozenRow));
}
}
}
private void CorrectRowFrozenStates(DataGridViewRow[] dataGridViewRows, int rowIndexInserted)
{
bool nextVisibleRowPresent = false, previousRowFrozen = true, nextRowFrozen = false, currentRowFrozen;
// Check if there is a visible row before the insertion point, and if it's frozen
int rowIndexTmp = this.Rows.GetPreviousRow(rowIndexInserted, DataGridViewElementStates.Visible);
if (rowIndexTmp != -1)
{
previousRowFrozen = (this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Frozen) == DataGridViewElementStates.Frozen;
}
// Check if there is a visible row at or after the insertion point, and if it's frozen
rowIndexTmp = this.Rows.GetNextRow(rowIndexInserted - 1, DataGridViewElementStates.Visible);
if (rowIndexTmp != -1)
{
nextVisibleRowPresent = true;
nextRowFrozen = (this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Frozen) == DataGridViewElementStates.Frozen;
}
for (int arrayIndex = 0; arrayIndex < dataGridViewRows.Length; arrayIndex++)
{
currentRowFrozen = ((DataGridViewRow)dataGridViewRows[arrayIndex]).Frozen;
if (!previousRowFrozen && currentRowFrozen)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddFrozenRow));
}
previousRowFrozen = currentRowFrozen;
if (arrayIndex == dataGridViewRows.Length - 1 &&
!currentRowFrozen &&
nextVisibleRowPresent &&
nextRowFrozen)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddNonFrozenRow));
}
}
}
private void CorrectRowFrozenStates(DataGridViewRow dataGridViewRow, int rowIndex, bool frozenStateChanging)
{
Debug.Assert(dataGridViewRow != null);
int rowIndexTmp;
if (((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Frozen) != 0 && !frozenStateChanging) ||
((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Frozen) == 0 && frozenStateChanging))
{
// make sure the previous visible rows are frozen as well
rowIndexTmp = this.Rows.GetPreviousRow(rowIndex,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
if (rowIndexTmp == -1)
{
int dataGridViewRowFirst = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (dataGridViewRowFirst != rowIndex)
{
rowIndexTmp = dataGridViewRowFirst;
}
}
while (rowIndexTmp != -1 && rowIndexTmp < rowIndex)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Frozen, true);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
}
}
else
{
// make sure the next visible rows are not frozen
rowIndexTmp = this.Rows.GetNextRow(rowIndex,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
if (rowIndexTmp == -1)
{
int dataGridViewRowLast = rowIndex;
do
{
rowIndexTmp = this.Rows.GetNextRow(dataGridViewRowLast,
DataGridViewElementStates.Visible);
if (rowIndexTmp != -1)
{
dataGridViewRowLast = rowIndexTmp;
}
}
while (rowIndexTmp != -1);
if (dataGridViewRowLast != rowIndex)
{
rowIndexTmp = dataGridViewRowLast;
}
}
while (rowIndexTmp != -1 && rowIndexTmp > rowIndex)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Frozen, false);
rowIndexTmp = this.Rows.GetPreviousRow(rowIndexTmp,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
}
}
private void CorrectRowIndexesAfterDeletion(int rowIndexDeleted)
{
Debug.Assert(rowIndexDeleted >= 0);
int rowsCount = this.Rows.Count;
for (int rowIndex = rowIndexDeleted; rowIndex < rowsCount; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Index >= 0)
{
dataGridViewRow.IndexInternal = dataGridViewRow.Index - 1;
Debug.Assert(dataGridViewRow.Index == rowIndex);
}
}
// Fix 'new' row index if existant
if (this.newRowIndex == rowIndexDeleted)
{
this.newRowIndex = -1; // No more 'new' row.
}
else if (this.newRowIndex != -1)
{
this.newRowIndex--;
}
}
private void CorrectRowIndexesAfterInsertion(int rowIndexInserted, int insertionCount)
{
Debug.Assert(rowIndexInserted >= 0);
Debug.Assert(insertionCount > 0);
int rowsCount = this.Rows.Count;
for (int rowIndex = rowIndexInserted + insertionCount; rowIndex < rowsCount; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Index >= 0)
{
dataGridViewRow.IndexInternal = dataGridViewRow.Index + insertionCount;
Debug.Assert(dataGridViewRow.Index == rowIndex);
}
}
// Lastly update the 'new' row index if needed.
if (this.newRowIndex != -1)
{
this.newRowIndex += insertionCount;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.CreateAccessibilityInstance"]/*' />
protected override AccessibleObject CreateAccessibilityInstance()
{
return new DataGridViewAccessibleObject(this);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.CreateControlsInstance"]/*' />
protected override Control.ControlCollection CreateControlsInstance()
{
return new DataGridViewControlCollection(this);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.CreateColumnsInstance"]/*' />
/// <devdoc>
/// Constructs the new instance of the Columns collection objects. Subclasses
/// should not call base.CreateColumnsInstance.
/// </devdoc>
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual DataGridViewColumnCollection CreateColumnsInstance()
{
return new DataGridViewColumnCollection(this);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.CreateRowsInstance"]/*' />
/// <devdoc>
/// Constructs the new instance of the Rows collection objects. Subclasses
/// should not call base.CreateRowsInstance.
/// </devdoc>
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual DataGridViewRowCollection CreateRowsInstance()
{
return new DataGridViewRowCollection(this);
}
private NativeMethods.RECT[] CreateScrollableRegion(Rectangle scroll)
{
if (this.cachedScrollableRegion != null)
{
return this.cachedScrollableRegion;
}
using (Region region = new Region(scroll))
{
IntPtr handle = IntPtr.Zero;
using (Graphics graphics = CreateGraphicsInternal())
{
handle = region.GetHrgn(graphics);
}
if (handle != IntPtr.Zero)
{
this.cachedScrollableRegion = UnsafeNativeMethods.GetRectsFromRegion(handle);
// SECREVIEW : This assert is safe since we created the native region.
//
IntSecurity.ObjectFromWin32Handle.Assert();
try
{
region.ReleaseHrgn(handle);
}
finally
{
CodeAccessPermission.RevertAssert();
}
}
}
return this.cachedScrollableRegion;
}
private void DiscardNewRow()
{
Debug.Assert(this.Rows.Count > 1);
Debug.Assert(this.newRowIndex != -1);
DataGridViewRowCancelEventArgs dgvrce = new DataGridViewRowCancelEventArgs(this.Rows[this.newRowIndex]);
OnUserDeletingRow(dgvrce);
if (dgvrce.Cancel)
{
return;
}
// Delete the 'new' row
Debug.Assert(this.newRowIndex == this.Rows.Count - 1);
DataGridViewRow dataGridViewRow = this.Rows[this.newRowIndex];
this.Rows.RemoveAtInternal(this.newRowIndex, false /*force*/);
Debug.Assert(dataGridViewRow.Index == -1);
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs(dataGridViewRow);
OnUserDeletedRow(dgvre);
// CorrectRowIndexesAfterDeletion resets this.newRowIndex to -1.
Debug.Assert(this.newRowIndex == -1);
if (this.AllowUserToAddRowsInternal)
{
this.newRowIndex = this.Rows.Count - 1;
Debug.Assert((this.Rows.GetRowState(this.newRowIndex) & DataGridViewElementStates.Visible) != 0);
Debug.Assert(this.ptCurrentCell.Y == this.newRowIndex);
OnDefaultValuesNeeded(new DataGridViewRowEventArgs(this.Rows[this.newRowIndex]));
InvalidateRowPrivate(this.newRowIndex);
}
}
private void DiscardZonesInScrollingArea(ref Rectangle rectScrollingArea,
int emptyBackgroundWidth,
int emptyBackgroundHeight,
int frozenVisibleRowsHeight,
bool discardFrozenColumns,
bool discardFrozenRows)
{
// Discard empty background
rectScrollingArea.Width -= emptyBackgroundWidth;
rectScrollingArea.Height -= emptyBackgroundHeight;
if (this.RightToLeftInternal)
{
rectScrollingArea.X += emptyBackgroundWidth;
}
if (discardFrozenColumns)
{
// Discard frozen columns
int frozenVisibleColumnsWidth = this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
if (!this.RightToLeftInternal)
{
rectScrollingArea.X += frozenVisibleColumnsWidth;
}
rectScrollingArea.Width -= frozenVisibleColumnsWidth;
}
if (discardFrozenRows)
{
// Discard frozen rows
rectScrollingArea.Y += frozenVisibleRowsHeight;
rectScrollingArea.Height -= frozenVisibleRowsHeight;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.DisplayedColumnCount"]/*' />
public int DisplayedColumnCount(bool includePartialColumns)
{
int cxMax = this.layout.Data.Width, cx = 0;
int completeColumns = 0, partialColumns = 0;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (dataGridViewColumn != null && cx < cxMax)
{
partialColumns++;
cx += dataGridViewColumn.Thickness;
if (cx <= cxMax)
{
completeColumns++;
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen,
DataGridViewElementStates.None);
}
}
if (cx < cxMax && this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0)
{
if (this.negOffset > 0)
{
cx -= this.negOffset;
completeColumns--;
}
dataGridViewColumn = (DataGridViewColumn)this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
Debug.Assert(dataGridViewColumn.Visible && !dataGridViewColumn.Frozen);
while (dataGridViewColumn != null && cx < cxMax)
{
partialColumns++;
cx += dataGridViewColumn.Thickness;
if (cx <= cxMax)
{
completeColumns++;
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
}
}
return includePartialColumns ? partialColumns : completeColumns;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.DisplayedRowCount"]/*' />
public int DisplayedRowCount(bool includePartialRow)
{
return includePartialRow ? (this.displayedBandsInfo.NumDisplayedFrozenRows + this.displayedBandsInfo.NumDisplayedScrollingRows) :
(this.displayedBandsInfo.NumTotallyDisplayedFrozenRows + this.displayedBandsInfo.NumTotallyDisplayedScrollingRows);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.Dispose"]/*' />
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] = true;
try
{
// Remove any Columns contained in this control
for (int i = 0; i < this.Columns.Count; i ++)
{
this.Columns[i].Dispose();
}
this.Columns.Clear();
UnwireScrollBarsEvents();
if (this.vertScrollBar != null)
{
this.vertScrollBar.Dispose();
this.vertScrollBar = null;
}
if (this.horizScrollBar != null)
{
this.horizScrollBar.Dispose();
this.horizScrollBar = null;
}
if (this.pens != null)
{
int nPenEntries = this.pens.Count;
if (nPenEntries > 0)
{
foreach (Pen pen in this.pens.Values)
{
pen.Dispose();
}
this.pens.Clear();
}
this.pens = null;
}
if (this.brushes != null)
{
int nBrushEntries = this.brushes.Count;
if (nBrushEntries > 0)
{
foreach (SolidBrush brush in this.brushes.Values)
{
brush.Dispose();
}
this.brushes.Clear();
}
this.brushes = null;
}
if (this.placeholderStringFormat != null)
{
this.placeholderStringFormat.Dispose();
this.placeholderStringFormat = null;
}
if (this.latestEditingControl != null)
{
this.latestEditingControl.Dispose();
this.latestEditingControl = null;
}
if (this.editingControl != null)
{
this.editingControl.Dispose();
this.editingControl = null;
}
if (this.editingPanel != null)
{
this.editingPanel.Dispose();
this.editingPanel = null;
}
if (this.gridPen != null)
{
this.gridPen.Dispose();
this.gridPen = null;
}
Debug.Assert(this.noSelectionChangeCount == 0);
if (this.dataConnection != null)
{
this.dataConnection.Dispose();
}
// DGV should dispose the tool tip control before disposing itself.
// vsw 559812.
this.toolTipControl.Dispose();
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] = false;
}
}
base.Dispose(disposing);
}
private void DrawColHeaderShadow(Graphics g, int mouseX)
{
Rectangle r = CalcColRelocationFeedbackRect(mouseX);
DrawShadowRect(r);
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_showColumnRelocationInsertion])
{
Rectangle rectInsertionBar = new Rectangle(0, this.layout.ColumnHeaders.Top, DATAGRIDVIEW_insertionBarWidth, this.layout.ColumnHeaders.Height);
// this.trackColumnEdge is the column preceeding the insertion point
if (this.trackColumnEdge == -1)
{
// Insert as first column
rectInsertionBar.X = GetColumnXFromIndex(this.Columns.GetFirstColumn(DataGridViewElementStates.Visible).Index);
if (this.RightToLeftInternal)
{
rectInsertionBar.X -= DATAGRIDVIEW_insertionBarWidth;
}
}
else
{
int offsetFromCenter = 0;
if (this.Columns.GetNextColumn(this.Columns[this.trackColumnEdge], DataGridViewElementStates.Visible, DataGridViewElementStates.None) == null)
{
if (!this.RightToLeftInternal)
{
offsetFromCenter = DATAGRIDVIEW_insertionBarWidth;
}
}
else
{
if (this.RightToLeftInternal)
{
offsetFromCenter = DATAGRIDVIEW_insertionBarWidth / 2 - 1;
}
else
{
offsetFromCenter = DATAGRIDVIEW_insertionBarWidth / 2 + 1;
}
}
if (this.RightToLeftInternal)
{
rectInsertionBar.X = Math.Max(this.layout.ColumnHeaders.X,
GetColumnXFromIndex(this.trackColumnEdge) - this.Columns[this.trackColumnEdge].Width - offsetFromCenter);
}
else
{
rectInsertionBar.X = Math.Min(GetColumnXFromIndex(this.trackColumnEdge) + this.Columns[this.trackColumnEdge].Width - offsetFromCenter,
this.layout.ColumnHeaders.Right - DATAGRIDVIEW_insertionBarWidth);
}
}
if (this.ApplyVisualStylesToHeaderCells)
{
g.FillRectangle(GetCachedBrush(SystemColors.HotTrack), rectInsertionBar);
}
else
{
ControlPaint.FillReversibleRectangle(RectangleToScreen(rectInsertionBar), Color.White);
}
}
}
/// <devdoc>
/// Draws an XOR region to give UI feedback for Column Resizing.
/// This looks just like the Splitter control's UI when resizing.
/// </devdoc>
private void DrawColSplitBar(int mouseX)
{
Rectangle r = CalcColResizeFeedbackRect(mouseX);
DrawSplitBar(r);
}
/// <devdoc>
/// Draws an XOR region to give UI feedback for Row Resizing.
/// This looks just like the Splitter control's UI when resizing.
/// </devdoc>
private void DrawRowSplitBar(int mouseY)
{
Rectangle r = CalcRowResizeFeedbackRect(mouseY);
DrawSplitBar(r);
}
private void DrawShadowRect(Rectangle r)
{
const byte DATAGRIDVIEW_shadowEdgeThickness = 3;
IntPtr parentHandle = this.Handle;
IntPtr dc = UnsafeNativeMethods.GetDCEx(new HandleRef(this, parentHandle), NativeMethods.NullHandleRef, NativeMethods.DCX_CACHE | NativeMethods.DCX_LOCKWINDOWUPDATE);
IntPtr halftone = ControlPaint.CreateHalftoneHBRUSH();
IntPtr saveBrush = SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, halftone));
SafeNativeMethods.PatBlt(new HandleRef(this, dc), r.X, r.Y, r.Width, DATAGRIDVIEW_shadowEdgeThickness, NativeMethods.PATINVERT);
SafeNativeMethods.PatBlt(new HandleRef(this, dc), r.X, r.Y + r.Height - DATAGRIDVIEW_shadowEdgeThickness, r.Width, DATAGRIDVIEW_shadowEdgeThickness, NativeMethods.PATINVERT);
SafeNativeMethods.PatBlt(new HandleRef(this, dc), r.X, r.Y + DATAGRIDVIEW_shadowEdgeThickness, DATAGRIDVIEW_shadowEdgeThickness, r.Height - 2 * DATAGRIDVIEW_shadowEdgeThickness, NativeMethods.PATINVERT);
SafeNativeMethods.PatBlt(new HandleRef(this, dc), r.X + r.Width - DATAGRIDVIEW_shadowEdgeThickness, r.Y + DATAGRIDVIEW_shadowEdgeThickness, DATAGRIDVIEW_shadowEdgeThickness, r.Height - 2 * DATAGRIDVIEW_shadowEdgeThickness, NativeMethods.PATINVERT);
SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, saveBrush));
SafeNativeMethods.DeleteObject(new HandleRef(null, halftone));
UnsafeNativeMethods.ReleaseDC(new HandleRef(this, parentHandle), new HandleRef(this, dc));
}
/// <devdoc>
/// Draws an XOR region to give UI feedback for Column/Row Resizing.
/// This looks just like the Splitter control's UI when resizing.
/// </devdoc>
private void DrawSplitBar(Rectangle r)
{
IntPtr parentHandle = this.Handle;
IntPtr dc = UnsafeNativeMethods.GetDCEx(new HandleRef(this, parentHandle), NativeMethods.NullHandleRef, NativeMethods.DCX_CACHE | NativeMethods.DCX_LOCKWINDOWUPDATE);
IntPtr halftone = ControlPaint.CreateHalftoneHBRUSH();
IntPtr saveBrush = SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, halftone));
SafeNativeMethods.PatBlt(new HandleRef(this, dc), r.X, r.Y, r.Width, r.Height, NativeMethods.PATINVERT);
SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, saveBrush));
SafeNativeMethods.DeleteObject(new HandleRef(null, halftone));
UnsafeNativeMethods.ReleaseDC(new HandleRef(this, parentHandle), new HandleRef(this, dc));
}
private void EditingControls_CommonMouseEventHandler(object sender, MouseEventArgs e, DataGridViewMouseEvent dgvme)
{
Debug.Assert(this.ptCurrentCell.X != -1);
int adjustedX = this.editingPanel.Location.X + e.X;
int adjustedY = this.editingPanel.Location.Y + e.Y;
if (sender == this.editingControl)
{
adjustedX += this.editingControl.Location.X;
adjustedY += this.editingControl.Location.Y;
}
if (dgvme == DataGridViewMouseEvent.MouseDown && e.Clicks == 1)
{
// Reset the flag that records single-click exposed as double-click.
this.dataGridViewOper[DATAGRIDVIEWOPER_lastEditCtrlClickDoubled] = false;
}
MouseEventArgs me = new MouseEventArgs(e.Button,
e.Clicks,
adjustedX,
adjustedY,
e.Delta);
HitTestInfo hti = HitTest(me.X, me.Y);
int mouseX = me.X - hti.ColumnX;
if (this.RightToLeftInternal)
{
mouseX += ((hti.col == -1) ? this.RowHeadersWidth : this.Columns[hti.col].Thickness);
}
DataGridViewCellMouseEventArgs dgvcme = new DataGridViewCellMouseEventArgs(hti.col, hti.row, mouseX, me.Y - hti.RowY, me);
try
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls] = true;
// Check to see if this is a CellMouseDoubleClick situation
if ((dgvme == DataGridViewMouseEvent.MouseDown ||
dgvme == DataGridViewMouseEvent.Click ||
dgvme == DataGridViewMouseEvent.MouseClick) &&
(DateTime.Now.Ticks - this.lastMouseClickInfo.timeStamp) / 10000 <= SystemInformation.DoubleClickTime &&
e.Button == this.lastMouseClickInfo.button &&
e.Clicks == 1 &&
dgvcme.ColumnIndex == this.lastMouseClickInfo.col &&
dgvcme.RowIndex == this.lastMouseClickInfo.row)
{
Size hotDoubleClickZone = SystemInformation.DoubleClickSize;
if (Math.Abs(dgvcme.X - this.lastMouseClickInfo.x) <= hotDoubleClickZone.Width / 2 &&
Math.Abs(dgvcme.Y - this.lastMouseClickInfo.y) <= hotDoubleClickZone.Height / 2)
{
me = new MouseEventArgs(e.Button,
2,
adjustedX,
adjustedY,
e.Delta);
dgvcme = new DataGridViewCellMouseEventArgs(dgvcme.ColumnIndex, dgvcme.RowIndex, dgvcme.X, dgvcme.Y, me);
switch (dgvme)
{
case DataGridViewMouseEvent.MouseDown:
{
OnMouseDown(me);
if (dgvcme.ColumnIndex < this.Columns.Count &&
dgvcme.RowIndex < this.Rows.Count)
{
OnCellMouseDown(dgvcme);
}
break;
}
case DataGridViewMouseEvent.Click:
{
OnDoubleClick(me);
if (e.Button == MouseButtons.Left &&
dgvcme.ColumnIndex < this.Columns.Count &&
dgvcme.RowIndex < this.Rows.Count)
{
OnCellDoubleClick(new DataGridViewCellEventArgs(dgvcme.ColumnIndex, dgvcme.RowIndex));
}
break;
}
case DataGridViewMouseEvent.MouseClick:
{
// Set the flag that prevents the triple-click to be exposed as a double-click
this.dataGridViewOper[DATAGRIDVIEWOPER_lastEditCtrlClickDoubled] = true;
OnMouseDoubleClick(me);
if (dgvcme.ColumnIndex < this.Columns.Count && dgvcme.RowIndex < this.Rows.Count)
{
OnCellMouseDoubleClick(dgvcme);
}
break;
}
}
return;
}
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_lastEditCtrlClickDoubled])
{
// Make sure that the triple-click is exposed as a single-click and not a double-click.
if (e.Clicks == 2)
{
me = new MouseEventArgs(e.Button,
1,
adjustedX,
adjustedY,
e.Delta);
dgvcme = new DataGridViewCellMouseEventArgs(hti.col, hti.row, mouseX, me.Y - hti.RowY, me);
}
switch (dgvme)
{
case DataGridViewMouseEvent.DoubleClick:
dgvme = DataGridViewMouseEvent.Click;
break;
case DataGridViewMouseEvent.MouseDoubleClick:
dgvme = DataGridViewMouseEvent.MouseClick;
break;
}
}
switch (dgvme)
{
case DataGridViewMouseEvent.Click:
OnClick(me);
if (e.Button == MouseButtons.Left &&
dgvcme.ColumnIndex < this.Columns.Count &&
dgvcme.RowIndex < this.Rows.Count)
{
OnCellClick(new DataGridViewCellEventArgs(dgvcme.ColumnIndex, dgvcme.RowIndex));
}
break;
case DataGridViewMouseEvent.DoubleClick:
OnDoubleClick(me);
if (e.Button == MouseButtons.Left &&
dgvcme.ColumnIndex < this.Columns.Count &&
dgvcme.RowIndex < this.Rows.Count)
{
OnCellDoubleClick(new DataGridViewCellEventArgs(dgvcme.ColumnIndex, dgvcme.RowIndex));
}
break;
case DataGridViewMouseEvent.MouseClick:
OnMouseClick(me);
if (dgvcme.ColumnIndex < this.Columns.Count &&
dgvcme.RowIndex < this.Rows.Count)
{
OnCellMouseClick(dgvcme);
}
break;
case DataGridViewMouseEvent.MouseDoubleClick:
OnMouseDoubleClick(me);
if (dgvcme.ColumnIndex < this.Columns.Count &&
dgvcme.RowIndex < this.Rows.Count)
{
OnCellMouseDoubleClick(dgvcme);
}
break;
case DataGridViewMouseEvent.MouseDown:
OnMouseDown(me);
if (dgvcme.ColumnIndex < this.Columns.Count &&
dgvcme.RowIndex < this.Rows.Count)
{
OnCellMouseDown(dgvcme);
}
break;
case DataGridViewMouseEvent.MouseUp:
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_nextMouseUpIsDouble])
{
MouseEventArgs meTmp = new MouseEventArgs(e.Button,
2,
adjustedX,
adjustedY,
e.Delta);
dgvcme = new DataGridViewCellMouseEventArgs(dgvcme.ColumnIndex, dgvcme.RowIndex, dgvcme.X, dgvcme.Y, meTmp);
}
OnCellMouseUp(dgvcme);
OnMouseUp(me);
break;
case DataGridViewMouseEvent.MouseMove:
OnCellMouseMove(dgvcme);
break;
}
}
finally
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls] = false;
}
}
private void EditingControls_Click(object sender, System.EventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
Debug.Assert(this.ptCurrentCell.X != -1);
System.Windows.Forms.MouseEventArgs me = e as System.Windows.Forms.MouseEventArgs;
if (me != null)
{
EditingControls_CommonMouseEventHandler(sender, me, DataGridViewMouseEvent.Click);
}
}
private void EditingControls_DoubleClick(object sender, System.EventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
Debug.Assert(this.ptCurrentCell.X != -1);
System.Windows.Forms.MouseEventArgs me = e as System.Windows.Forms.MouseEventArgs;
if (me != null)
{
EditingControls_CommonMouseEventHandler(sender, me, DataGridViewMouseEvent.DoubleClick);
}
}
private void EditingControls_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
EditingControls_CommonMouseEventHandler(sender, e, DataGridViewMouseEvent.MouseClick);
}
private void EditingControls_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
EditingControls_CommonMouseEventHandler(sender, e, DataGridViewMouseEvent.MouseDoubleClick);
}
private void EditingControls_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
EditingControls_CommonMouseEventHandler(sender, e, DataGridViewMouseEvent.MouseDown);
}
private void EditingControls_MouseEnter(object sender, System.EventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
if (sender == this.editingPanel)
{
Debug.Assert(this.editingControl != null);
Debug.Assert(!this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet]);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet] = true;
this.oldCursor = this.Cursor;
this.CursorInternal = ((IDataGridViewEditingControl)this.editingControl).EditingPanelCursor;
}
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseEnterExpected])
{
OnMouseEnter(EventArgs.Empty);
}
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
}
private void EditingControls_MouseLeave(object sender, System.EventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
if (sender == this.editingPanel)
{
Debug.Assert(this.editingControl != null);
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet] = false;
this.CursorInternal = this.oldCursor;
}
}
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
Point ptMouse = PointToClient(Control.MousePosition);
if (!this.ClientRectangle.Contains(ptMouse))
{
OnMouseLeave(EventArgs.Empty);
}
}
private void EditingControls_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
EditingControls_CommonMouseEventHandler(sender, e, DataGridViewMouseEvent.MouseMove);
}
private void EditingControls_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Debug.Assert(sender == this.editingControl || sender == this.editingPanel);
EditingControls_CommonMouseEventHandler(sender, e, DataGridViewMouseEvent.MouseUp);
}
private void EndColumnHeadersResize(MouseEventArgs e)
{
try
{
if (this.currentRowSplitBar != -1)
{
Invalidate(CalcRowResizeFeedbackRect(this.currentRowSplitBar), true);
this.lastRowSplitBar = this.currentRowSplitBar = -1;
}
int y = Math.Min(e.Y + this.mouseBarOffset, this.layout.Data.Bottom - 1);
int delta = y - this.layout.ColumnHeaders.Y - this.ColumnHeadersHeight + 1;
if (this.trackRowAnchor != y && delta != 0)
{
this.ColumnHeadersHeight += delta;
}
}
finally
{
RealeaseMouse();
}
}
private void EndColumnRelocation(MouseEventArgs e, HitTestInfo hti)
{
try
{
if (this.lastHeaderShadow != -1)
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_showColumnRelocationInsertion] = false;
this.trackColumnEdge = -1;
this.lastHeaderShadow = -1;
Invalidate(Rectangle.Union(this.layout.TopLeftHeader, this.layout.ColumnHeaders));
}
int previousColumnIndex;
if (ColumnRelocationTarget(e, hti, out previousColumnIndex))
{
if (previousColumnIndex == -1)
{
this.Columns[this.trackColumn].DisplayIndex = 0;
}
else if (this.Columns[this.trackColumn].DisplayIndex > this.Columns[previousColumnIndex].DisplayIndex)
{
this.Columns[this.trackColumn].DisplayIndex = this.Columns[previousColumnIndex].DisplayIndex + 1;
}
else
{
this.Columns[this.trackColumn].DisplayIndex = this.Columns[previousColumnIndex].DisplayIndex;
}
}
}
finally
{
RealeaseMouse();
}
}
private void EndColumnResize(MouseEventArgs e)
{
try
{
EndColumnResize(e.X);
}
finally
{
RealeaseMouse();
}
}
private void EndColumnResize(int x)
{
int newX, delta;
if (this.RightToLeftInternal)
{
newX = Math.Max(x + this.mouseBarOffset, this.layout.Data.X);
delta = GetColumnXFromIndex(this.trackColumn) - this.Columns[this.trackColumn].Thickness - newX + 1;
}
else
{
newX = Math.Min(x + this.mouseBarOffset, this.layout.Data.Right - 1);
delta = newX - (GetColumnXFromIndex(this.trackColumn) + this.Columns[this.trackColumn].Thickness) + 1;
}
if (this.trackColAnchor != newX && delta != 0)
{
int proposed = this.Columns[this.trackColumn].Thickness + delta;
Debug.Assert(proposed >= this.Columns[this.trackColumn].MinimumThickness);
Debug.Assert(proposed <= DataGridViewBand.maxBandThickness);
this.Columns[this.trackColumn].Thickness = proposed;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.EndEdit1"]/*' />
public bool EndEdit()
{
return EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.EndEdit2"]/*' />
public bool EndEdit(DataGridViewDataErrorContexts context)
{
if (this.EditMode == DataGridViewEditMode.EditOnEnter)
{
return CommitEdit(context);
}
else
{
return EndEdit(context,
DataGridViewValidateCellInternal.Never /*validateCell*/,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
true /*keepFocus*/,
true /*resetCurrentCell*/,
true /*resetAnchorCell*/);
}
}
private bool EndEdit(DataGridViewDataErrorContexts context,
DataGridViewValidateCellInternal validateCell,
bool fireCellLeave,
bool fireCellEnter,
bool fireRowLeave,
bool fireRowEnter,
bool fireLeave,
bool keepFocus,
bool resetCurrentCell,
bool resetAnchorCell)
{
if (this.ptCurrentCell.X == -1)
{
return true;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_inEndEdit] = true;
try
{
int curRowIndex = this.ptCurrentCell.Y;
int curColIndex = this.ptCurrentCell.X;
DataGridViewCell dataGridViewCurrentCell = this.CurrentCellInternal;
DataGridViewDataErrorEventArgs dgvdee = CommitEdit(ref dataGridViewCurrentCell, context, validateCell,
fireCellLeave, fireCellEnter, fireRowLeave, fireRowEnter, fireLeave);
if (dgvdee != null)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
if (dgvdee.Cancel)
{
return false;
}
dgvdee = CancelEditPrivate(/*ref dataGridViewCurrentCell, context*/); // restore old value
if (null != dgvdee)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
if (dgvdee.Cancel)
{
return false;
}
}
}
if (!this.IsCurrentCellInEditMode)
{
return true;
}
if (curRowIndex != this.ptCurrentCell.Y || curColIndex != this.ptCurrentCell.X)
{
return true;
}
if (this.editingControl != null)
{
UnwireEditingControlEvents();
this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseOverRemovedEditingCtrl] = this.MouseOverEditingControl;
this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseOverRemovedEditingPanel] = this.MouseOverEditingPanel;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlChanging] = true;
try
{
dataGridViewCurrentCell.DetachEditingControl();
}
finally
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlChanging] = false;
}
ImeMode editingControlImeMode = this.editingControl.CachedImeMode; // If in restricted mode, ImeMode will be Disable.
this.latestEditingControl = this.editingControl;
Debug.Assert(this.editingPanel == null || this.editingPanel.Controls.Count == 0);
this.editingControl = null;
InvalidateCellPrivate(this.ptCurrentCell.X, this.ptCurrentCell.Y);
if (this.EditMode == DataGridViewEditMode.EditOnEnter)
{
if (resetCurrentCell)
{
bool success = SetCurrentCellAddressCore(-1, -1, resetAnchorCell, false, false);
Debug.Assert(success);
}
}
if (keepFocus)
{
// Debug.Assert(this.CanFocus || this.Focused); // Invalid assertion (VS Whidbey 325154)
FocusInternal();
}
this.ImeMode = editingControlImeMode;
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode] = false;
InvalidateCellPrivate(this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
if (!IsInnerCellOutOfBounds(curColIndex, curRowIndex))
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(curColIndex, curRowIndex);
OnCellEndEdit(dgvce);
}
return true;
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inEndEdit] = false;
}
}
private void EndRowHeadersResize(MouseEventArgs e)
{
try
{
if (this.currentColSplitBar != -1)
{
Invalidate(CalcColResizeFeedbackRect(this.currentColSplitBar), true);
this.lastColSplitBar = this.currentColSplitBar = -1;
}
int x, delta;
if (this.RightToLeftInternal)
{
x = Math.Max(e.X + this.mouseBarOffset, this.layout.Data.Left - 1);
delta = this.layout.RowHeaders.Right - this.RowHeadersWidth - x - 1;
}
else
{
x = Math.Min(e.X + this.mouseBarOffset, this.layout.Data.Right - 1);
delta = x - this.layout.RowHeaders.X - this.RowHeadersWidth + 1;
}
if (this.trackColAnchor != x && delta != 0)
{
this.RowHeadersWidth += delta;
}
}
finally
{
RealeaseMouse();
}
}
private void EndRowResize(MouseEventArgs e)
{
try
{
if (this.currentRowSplitBar != -1)
{
Invalidate(CalcRowResizeFeedbackRect(this.currentRowSplitBar), true);
this.lastRowSplitBar = this.currentRowSplitBar = -1;
}
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(this.trackRow);
int height, minimumHeight;
dataGridViewRow.GetHeightInfo(this.trackRow, out height, out minimumHeight);
int y = Math.Min(e.Y + this.mouseBarOffset, this.layout.Data.Bottom - 1);
int delta = y - (GetRowYFromIndex(this.trackRow) + height) + 1;
if (this.trackRowAnchor != y && delta != 0)
{
int proposedHeight = height + delta;
proposedHeight = Math.Max(proposedHeight, minimumHeight);
if (!OnRowHeightInfoPushed(this.trackRow, proposedHeight, minimumHeight))
{
if (dataGridViewRow.Index == -1)
{
dataGridViewRow = this.Rows[this.trackRow]; // Unsharing row
}
Debug.Assert(this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None);
dataGridViewRow.ThicknessInternal = proposedHeight;
}
}
}
finally
{
RealeaseMouse();
}
}
private void ExitBulkLayout(bool invalidInAdjustFillingColumns)
{
if (this.inBulkLayoutCount > 0)
{
this.inBulkLayoutCount--;
if (this.inBulkLayoutCount == 0)
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, invalidInAdjustFillingColumns, false /*repositionEditingControl*/);
}
}
}
private void ExitBulkPaint(int columnIndex, int rowIndex)
{
if (this.inBulkPaintCount > 0)
{
this.inBulkPaintCount--;
if (this.inBulkPaintCount == 0)
{
if (columnIndex >= 0)
{
InvalidateColumnInternal(columnIndex);
}
else if (rowIndex >= 0)
{
InvalidateRowPrivate(rowIndex);
}
else
{
Invalidate();
}
}
}
}
private void FirstVisibleScrollingRowTempted(int rowIndex)
{
Debug.Assert(rowIndex >= 0);
Debug.Assert(rowIndex < this.Rows.Count);
Debug.Assert((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) != 0);
Debug.Assert((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Frozen) == 0);
int displayHeight = this.layout.Data.Height;
if (displayHeight <= 0)
{
return;
}
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
if (totalVisibleFrozenHeight < displayHeight)
{
this.displayedBandsInfo.FirstDisplayedScrollingRow = rowIndex;
}
}
private void FlushDisplayedChanged()
{
if (this.displayedBandsInfo.Dirty && this.Visible)
{
// Handle the rows
if (!this.RowHeadersVisible && this.Columns.GetColumnCount(DataGridViewElementStates.Visible) == 0)
{
// All rows are hidden
UpdateRowsDisplayedState(false /*displayed*/);
}
else
{
Rectangle rectScreen = Screen.FromControl(this).WorkingArea;
int maxDisplayedRows = (int) (rectScreen.Height / DataGridViewBand.minBandThickness);
// Make sure all displayed scrolling rows have the Displayed state.
int rowIndexTmp = this.displayedBandsInfo.FirstDisplayedScrollingRow;
if (rowIndexTmp != -1)
{
int numDisplayedScrollingRows = this.displayedBandsInfo.NumDisplayedScrollingRows;
Debug.Assert(numDisplayedScrollingRows > 0);
while (numDisplayedScrollingRows > 0)
{
Debug.Assert(rowIndexTmp != -1);
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) == 0)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, true);
}
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
numDisplayedScrollingRows--;
}
int rowIndexTmp2 = rowIndexTmp;
// Make sure all scrolling rows before FirstDisplayedScrollingRow have their Displayed state set to false
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow != -1);
rowIndexTmp = this.Rows.GetPreviousRow(this.displayedBandsInfo.FirstDisplayedScrollingRow, DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
while (rowIndexTmp != -1 && (this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, false);
rowIndexTmp = this.Rows.GetPreviousRow(rowIndexTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
}
// Make sure all rows below last displayed scrolling row have Displayed state set to false (next loop)
rowIndexTmp = rowIndexTmp2;
}
else
{
// No displayed scrolling rows. Make sure all non-frozen rows have their Displayed state set to false (next loop)
rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
}
while (rowIndexTmp != -1 && (this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, false);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
}
// Make sure all displayed frozen rows have their Displayed state set to true
int numDisplayedFrozenRows = this.displayedBandsInfo.NumDisplayedFrozenRows;
rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (numDisplayedFrozenRows > 0)
{
Debug.Assert(rowIndexTmp != -1);
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) == 0)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, true);
}
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
numDisplayedFrozenRows--;
}
// Make sure all non-displayed frozen rows have their Displayed state set to false
while (rowIndexTmp != -1 && (this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, false);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
// Treat the cases where the old displayed rows are completely disjoint from the new displayed rows
int lastDisplayedFrozenRowIndex = -1;
int lastDisplayedScrollingRowIndex = -1;
if (this.displayedBandsInfo.NumDisplayedFrozenRows > 0)
{
int firstDisplayedFrozenRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
Debug.Assert(firstDisplayedFrozenRowIndex != -1);
if (this.displayedBandsInfo.NumDisplayedFrozenRows > 1)
{
lastDisplayedFrozenRowIndex = this.Rows.GetNextRow(firstDisplayedFrozenRowIndex, DataGridViewElementStates.Visible, this.displayedBandsInfo.NumDisplayedFrozenRows-2 /*skipRows*/);
}
else
{
lastDisplayedFrozenRowIndex = firstDisplayedFrozenRowIndex;
}
}
if (this.displayedBandsInfo.FirstDisplayedScrollingRow != -1)
{
if (this.displayedBandsInfo.NumDisplayedScrollingRows > 1)
{
lastDisplayedScrollingRowIndex = this.Rows.GetNextRow(this.displayedBandsInfo.FirstDisplayedScrollingRow, DataGridViewElementStates.Visible, this.displayedBandsInfo.NumDisplayedScrollingRows - 2 /*skipRows*/);
}
else
{
lastDisplayedScrollingRowIndex = this.displayedBandsInfo.FirstDisplayedScrollingRow;
}
}
rowIndexTmp = this.displayedBandsInfo.OldFirstDisplayedScrollingRow;
while (rowIndexTmp != -1 &&
rowIndexTmp < this.displayedBandsInfo.FirstDisplayedScrollingRow &&
!RowNeedsDisplayedState(rowIndexTmp, lastDisplayedFrozenRowIndex, lastDisplayedScrollingRowIndex))
{
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) == 0)
{
break;
}
else
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, false);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
}
}
rowIndexTmp = this.displayedBandsInfo.OldFirstDisplayedScrollingRow;
if (rowIndexTmp != -1 &&
rowIndexTmp < this.Rows.Count &&
(this.displayedBandsInfo.FirstDisplayedScrollingRow == -1 || this.displayedBandsInfo.FirstDisplayedScrollingRow < rowIndexTmp) &&
!RowNeedsDisplayedState(rowIndexTmp, lastDisplayedFrozenRowIndex, lastDisplayedScrollingRowIndex))
{
while (rowIndexTmp != -1)
{
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) == 0)
{
break;
}
else
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, false);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
}
}
}
if (this.displayedBandsInfo.RowInsertionOccurred)
{
// Adjust the scrolling rows that were pushed down by the rows insertion
rowIndexTmp = this.displayedBandsInfo.OldFirstDisplayedScrollingRow;
if (rowIndexTmp != -1)
{
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible, this.displayedBandsInfo.OldNumDisplayedScrollingRows - 1);
if (rowIndexTmp == -1)
{
rowIndexTmp = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
}
int rowCount = 0;
while (rowIndexTmp != -1 &&
rowCount <= maxDisplayedRows &&
!RowNeedsDisplayedState(rowIndexTmp, lastDisplayedFrozenRowIndex, lastDisplayedScrollingRowIndex))
{
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, false);
}
rowIndexTmp = this.Rows.GetPreviousRow(rowIndexTmp, DataGridViewElementStates.Visible);
rowCount++;
}
}
// Adjust the frozen rows that were pushed down by the rows insertion
rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
if (rowIndexTmp != -1)
{
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen, this.displayedBandsInfo.OldNumDisplayedFrozenRows - 1);
if (rowIndexTmp == -1)
{
rowIndexTmp = this.Rows.GetLastRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
int rowCount = 0;
while (rowIndexTmp != -1 &&
rowCount <= maxDisplayedRows &&
!RowNeedsDisplayedState(rowIndexTmp, lastDisplayedFrozenRowIndex, lastDisplayedScrollingRowIndex))
{
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, false);
}
rowIndexTmp = this.Rows.GetPreviousRow(rowIndexTmp, DataGridViewElementStates.Visible);
rowCount++;
}
}
}
#if DEBUG
for (rowIndexTmp = 0; rowIndexTmp < this.Rows.Count; rowIndexTmp++)
{
DataGridViewElementStates rowStateDbg = this.Rows.GetRowState(rowIndexTmp);
bool rowNeedsDisplayedState = RowNeedsDisplayedState(rowIndexTmp, lastDisplayedFrozenRowIndex, lastDisplayedScrollingRowIndex);
if (((rowStateDbg & DataGridViewElementStates.Displayed) != 0) != rowNeedsDisplayedState)
{
Debug.Fail("Unexpected Displayed state for row");
}
}
#endif
}
// Handle the columns
if (!this.ColumnHeadersVisible && this.Rows.GetRowCount(DataGridViewElementStates.Visible) == 0)
{
// All columns are hidden
UpdateColumnsDisplayedState(false /*displayed*/);
}
else
{
// Make sure all displayed scrolling columns have the Displayed state.
DataGridViewColumn dataGridViewColumnTmp;
int columnIndexTmp = this.displayedBandsInfo.FirstDisplayedScrollingCol;
if (columnIndexTmp != -1)
{
int numDisplayedScrollingCols = this.displayedBandsInfo.NumDisplayedScrollingCols;
Debug.Assert(numDisplayedScrollingCols > 0);
dataGridViewColumnTmp = this.Columns[columnIndexTmp];
while (numDisplayedScrollingCols > 0)
{
Debug.Assert(dataGridViewColumnTmp != null);
if (!dataGridViewColumnTmp.Displayed)
{
dataGridViewColumnTmp.DisplayedInternal = true;
}
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
numDisplayedScrollingCols--;
}
DataGridViewColumn dataGridViewColumnTmp2 = dataGridViewColumnTmp;
// Make sure all scrolling columns before FirstDisplayedScrollingCol have their Displayed state set to false
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingCol != -1);
dataGridViewColumnTmp = this.Columns.GetPreviousColumn(this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol], DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
while (dataGridViewColumnTmp != null && dataGridViewColumnTmp.Displayed)
{
dataGridViewColumnTmp.DisplayedInternal = false;
dataGridViewColumnTmp = this.Columns.GetPreviousColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
}
// Make sure all columns after last displayed scrolling column have Displayed state set to false (next loop)
dataGridViewColumnTmp = dataGridViewColumnTmp2;
}
else
{
// No displayed scrolling columns. Make sure all non-frozen columns have their Displayed state set to false (next loop)
dataGridViewColumnTmp = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
}
while (dataGridViewColumnTmp != null && dataGridViewColumnTmp.Displayed)
{
dataGridViewColumnTmp.DisplayedInternal = false;
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
// Make sure all displayed frozen columns have their Displayed state set to true
int numDisplayedFrozenCols = this.displayedBandsInfo.NumDisplayedFrozenCols;
dataGridViewColumnTmp = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (numDisplayedFrozenCols > 0)
{
Debug.Assert(dataGridViewColumnTmp != null);
if (!dataGridViewColumnTmp.Displayed)
{
dataGridViewColumnTmp.DisplayedInternal = true;
}
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen, DataGridViewElementStates.None);
numDisplayedFrozenCols--;
}
// Make sure all non-displayed frozen columns have their Displayed state set to false
while (dataGridViewColumnTmp != null && dataGridViewColumnTmp.Displayed)
{
dataGridViewColumnTmp.DisplayedInternal = false;
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen, DataGridViewElementStates.None);
}
// Treat the cases where the old displayed columns are completely disjoint from the new displayed columns
columnIndexTmp = this.displayedBandsInfo.OldFirstDisplayedScrollingCol;
while (columnIndexTmp != -1 &&
columnIndexTmp < this.Columns.Count &&
this.displayedBandsInfo.FirstDisplayedScrollingCol != -1 &&
columnIndexTmp != this.displayedBandsInfo.FirstDisplayedScrollingCol &&
this.Columns.DisplayInOrder(columnIndexTmp, this.displayedBandsInfo.FirstDisplayedScrollingCol) &&
!ColumnNeedsDisplayedState(this.Columns[columnIndexTmp]))
{
dataGridViewColumnTmp = this.Columns[columnIndexTmp];
if (!dataGridViewColumnTmp.Displayed)
{
break;
}
else
{
dataGridViewColumnTmp.DisplayedInternal = false;
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
columnIndexTmp = (dataGridViewColumnTmp == null) ? -1 : dataGridViewColumnTmp.Index;
}
}
columnIndexTmp = this.displayedBandsInfo.OldFirstDisplayedScrollingCol;
if (columnIndexTmp != -1 &&
columnIndexTmp < this.Columns.Count &&
(this.displayedBandsInfo.FirstDisplayedScrollingCol == -1 || (this.displayedBandsInfo.FirstDisplayedScrollingCol != columnIndexTmp && this.Columns.DisplayInOrder(this.displayedBandsInfo.FirstDisplayedScrollingCol, columnIndexTmp))) &&
!ColumnNeedsDisplayedState(this.Columns[columnIndexTmp]))
{
dataGridViewColumnTmp = this.Columns[columnIndexTmp];
while (dataGridViewColumnTmp != null)
{
if (!dataGridViewColumnTmp.Displayed)
{
break;
}
else
{
dataGridViewColumnTmp.DisplayedInternal = false;
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
}
}
if (this.displayedBandsInfo.ColumnInsertionOccurred)
{
dataGridViewColumnTmp = this.Columns[this.Columns.Count - 1];
while (dataGridViewColumnTmp != null && !ColumnNeedsDisplayedState(dataGridViewColumnTmp))
{
if (dataGridViewColumnTmp.Displayed)
{
dataGridViewColumnTmp.DisplayedInternal = false;
}
dataGridViewColumnTmp = this.Columns.GetPreviousColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
}
#if DEBUG
for (columnIndexTmp = 0; columnIndexTmp < this.Columns.Count; columnIndexTmp++)
{
DataGridViewElementStates colStateDbg = this.Columns[columnIndexTmp].State;
bool columnNeedsDisplayedState = ColumnNeedsDisplayedState(this.Columns[columnIndexTmp]);
if (((colStateDbg & DataGridViewElementStates.Displayed) != 0) != columnNeedsDisplayedState)
{
Debug.Fail("Unexpected Displayed state for column");
}
}
#endif
}
this.displayedBandsInfo.Dirty = false;
}
}
private void FlushDisplayIndexChanged(bool raiseEvent)
{
foreach (DataGridViewColumn dataGridViewColumn in this.Columns)
{
if (dataGridViewColumn.DisplayIndexHasChanged)
{
dataGridViewColumn.DisplayIndexHasChanged = false;
if (raiseEvent)
{
OnColumnDisplayIndexChanged(dataGridViewColumn);
}
}
}
}
private void FlushSelectionChanged()
{
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_raiseSelectionChanged])
{
OnSelectionChanged(EventArgs.Empty);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.GetAccessibilityObjectById"]/*' />
protected override AccessibleObject GetAccessibilityObjectById(int objectId)
{
// decrement the objectId because in our implementation of AccessibilityClient notitification objectId's are 1 - based.
// 0 == NativeMethods.CHILDID_SELF corresponds to the AccessibleObject itself
return this.AccessibilityObject.GetChild(objectId - 1);
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
internal SolidBrush GetCachedBrush(Color color)
{
SolidBrush brush = (SolidBrush) this.brushes[color];
if (brush == null)
{
brush = new SolidBrush(color);
this.brushes.Add(color, brush);
}
return brush;
}
#if DGV_GDI
internal WindowsSolidBrush GetCachedWindowsBrush(Color color)
{
WindowsSolidBrush brush = (WindowsSolidBrush)this.brushes[color];
if (brush == null)
{
brush = new WindowsSolidBrush(color);
this.brushes.Add(color, brush);
}
return brush;
}
#endif // DGV_GDI
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
internal Pen GetCachedPen(Color color)
{
Pen pen = (Pen) this.pens[color];
if (pen == null)
{
pen = new Pen(color);
this.pens.Add(color, pen);
}
return pen;
}
#if DGV_GDI
internal WindowsPen GetCachedWindowsPen(Color color)
{
WindowsPen pen = (WindowsPen)this.pens[color];
if (pen == null)
{
pen = new WindowsPen(color);
this.pens.Add(color, pen);
}
return pen;
}
#endif // DGV_GDI
internal TypeConverter GetCachedTypeConverter(Type type)
{
if (this.converters.ContainsKey(type))
{
return (TypeConverter)this.converters[type];
}
TypeConverter converter = TypeDescriptor.GetConverter(type);
this.converters.Add(type, converter);
return converter;
}
internal Rectangle GetCellAdjustedDisplayRectangle(int columnIndex, int rowIndex, bool cutOverflow)
{
Rectangle rect = GetCellDisplayRectangle(columnIndex, rowIndex, cutOverflow);
if (!rect.IsEmpty)
{
if (this.SingleVerticalBorderAdded && columnIndex == this.FirstDisplayedColumnIndex)
{
if (!this.RightToLeftInternal)
{
rect.X--;
}
rect.Width++;
}
if (this.SingleHorizontalBorderAdded && rowIndex == this.FirstDisplayedRowIndex)
{
rect.Y--;
rect.Height++;
}
}
return rect;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.GetCellCount"]/*' />
[
SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes"), // using specialized DataGridViewCellLinkedList class instead of generics
]
public int GetCellCount(DataGridViewElementStates includeFilter)
{
if ((includeFilter & ~(DataGridViewElementStates.Displayed | DataGridViewElementStates.Frozen | DataGridViewElementStates.Resizable |
DataGridViewElementStates.ReadOnly | DataGridViewElementStates.Selected | DataGridViewElementStates.Visible)) != 0)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_InvalidDataGridViewElementStateCombination, "includeFilter"));
}
int cellCount = 0;
bool displayedRequired, frozenRequired, resizableRequired, readOnlyRequired, visibleRequired;
if ((includeFilter & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
{
if (includeFilter == DataGridViewElementStates.Selected)
{
cellCount = this.individualSelectedCells.Count;
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
// If we change the design and decide that SelectAll() should use band selection,
// we need to take the bands into account.
return cellCount;
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
return cellCount + this.selectedBandIndexes.Count * this.Rows.Count;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
return cellCount + this.selectedBandIndexes.Count * this.Columns.Count;
}
}
}
displayedRequired = (includeFilter & DataGridViewElementStates.Displayed) == DataGridViewElementStates.Displayed;
frozenRequired = (includeFilter & DataGridViewElementStates.Frozen) == DataGridViewElementStates.Frozen;
resizableRequired = (includeFilter & DataGridViewElementStates.Resizable) == DataGridViewElementStates.Resizable;
readOnlyRequired = (includeFilter & DataGridViewElementStates.ReadOnly) == DataGridViewElementStates.ReadOnly;
visibleRequired = (includeFilter & DataGridViewElementStates.Visible) == DataGridViewElementStates.Visible;
foreach (DataGridViewCell dataGridViewCell in this.individualSelectedCells)
{
if (GetCellCount_CellIncluded(dataGridViewCell, dataGridViewCell.RowIndex, displayedRequired, frozenRequired, resizableRequired, readOnlyRequired, visibleRequired))
{
cellCount++;
}
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
// If we change the design and decide that SelectAll() should use band selection,
// we need to take the bands into account.
return cellCount;
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
foreach (int columnIndex in this.selectedBandIndexes)
{
DataGridViewCell dataGridViewCell = dataGridViewRow.Cells[columnIndex];
if (GetCellCount_CellIncluded(dataGridViewCell, rowIndex, displayedRequired, frozenRequired, resizableRequired, readOnlyRequired, visibleRequired))
{
cellCount++;
}
}
}
return cellCount;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
foreach (int rowIndex in this.selectedBandIndexes)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
foreach (DataGridViewCell dataGridViewCell in dataGridViewRow.Cells)
{
if (GetCellCount_CellIncluded(dataGridViewCell, rowIndex, displayedRequired, frozenRequired, resizableRequired, readOnlyRequired, visibleRequired))
{
cellCount++;
}
}
}
return cellCount;
}
}
}
if ((includeFilter == DataGridViewElementStates.ReadOnly && this.ReadOnly) ||
includeFilter == DataGridViewElementStates.None)
{
return this.Rows.Count * this.Columns.Count;
}
displayedRequired = (includeFilter & DataGridViewElementStates.Displayed) == DataGridViewElementStates.Displayed;
frozenRequired = (includeFilter & DataGridViewElementStates.Frozen) == DataGridViewElementStates.Frozen;
resizableRequired = (includeFilter & DataGridViewElementStates.Resizable) == DataGridViewElementStates.Resizable;
readOnlyRequired = (includeFilter & DataGridViewElementStates.ReadOnly) == DataGridViewElementStates.ReadOnly;
visibleRequired = (includeFilter & DataGridViewElementStates.Visible) == DataGridViewElementStates.Visible;
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (!visibleRequired || (this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) != 0)
{
foreach (DataGridViewCell dataGridViewCell in dataGridViewRow.Cells)
{
if (GetCellCount_CellIncluded(dataGridViewCell, rowIndex, displayedRequired, frozenRequired, resizableRequired, readOnlyRequired, visibleRequired))
{
cellCount++;
}
}
}
}
return cellCount;
}
private bool GetCellCount_CellIncluded(DataGridViewCell dataGridViewCell,
int rowIndex,
bool displayedRequired,
bool frozenRequired,
bool resizableRequired,
bool readOnlyRequired,
bool visibleRequired)
{
Debug.Assert(dataGridViewCell != null);
Debug.Assert(rowIndex >= 0);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if (displayedRequired)
{
bool cellDisplayed = (rowState & DataGridViewElementStates.Displayed) != 0 &&
dataGridViewCell.OwningColumn.Displayed;
if (!cellDisplayed)
{
return false;
}
}
if (frozenRequired)
{
bool cellFrozen = (rowState & DataGridViewElementStates.Frozen) != 0 ||
dataGridViewCell.OwningColumn.Frozen ||
dataGridViewCell.StateIncludes(DataGridViewElementStates.Frozen);
if (!cellFrozen)
{
return false;
}
}
if (resizableRequired)
{
if (!RowIsResizable(rowIndex) && dataGridViewCell.OwningColumn.Resizable != DataGridViewTriState.True)
{
return false;
}
}
if (readOnlyRequired)
{
bool cellReadOnly = this.ReadOnly ||
(rowState & DataGridViewElementStates.ReadOnly) != 0 ||
dataGridViewCell.OwningColumn.ReadOnly ||
dataGridViewCell.StateIncludes(DataGridViewElementStates.ReadOnly);
if (!cellReadOnly)
{
return false;
}
}
if (visibleRequired)
{
bool cellVisible = (rowState & DataGridViewElementStates.Visible) != 0 &&
dataGridViewCell.OwningColumn.Visible;
if (!cellVisible)
{
return false;
}
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.GetCellDisplayRectangle"]/*' />
public Rectangle GetCellDisplayRectangle(int columnIndex, int rowIndex, bool cutOverflow)
{
Rectangle rowRect;
Rectangle columnRect;
if (columnIndex >= 0)
{
if (columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
columnRect = GetColumnDisplayRectanglePrivate(columnIndex, cutOverflow);
}
else
{
if (columnIndex != -1)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex >= 0)
{
columnRect = this.layout.RowHeaders;
}
else
{
columnRect = this.layout.TopLeftHeader;
}
}
if (rowIndex >= 0)
{
if (rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
rowRect = GetRowDisplayRectanglePrivate(rowIndex, cutOverflow);
}
else
{
if (rowIndex != -1)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= 0)
{
rowRect = this.layout.ColumnHeaders;
}
else
{
rowRect = this.layout.TopLeftHeader;
}
}
if (!cutOverflow)
{
int height = rowRect.Bottom - columnRect.Bottom;
if (height > 0)
{
columnRect.Height += height;
}
int width;
if (this.RightToLeftInternal)
{
width = rowRect.X - columnRect.X;
if (width > 0)
{
rowRect.Width += width;
rowRect.X -= width;
}
}
else
{
width = columnRect.Right - rowRect.Right;
if (width > 0)
{
rowRect.Width += width;
}
}
}
rowRect.Intersect(columnRect);
return rowRect;
}
internal DataGridViewCell GetCellInternal(int columnIndex, int rowIndex)
{
Debug.Assert(columnIndex >= -1 && columnIndex < this.Columns.Count);
Debug.Assert(rowIndex >= -1 && rowIndex < this.Rows.Count);
if (rowIndex >= 0)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
Debug.Assert(dataGridViewRow != null);
if (columnIndex >= 0)
{
return dataGridViewRow.Cells[columnIndex];
}
else
{
return dataGridViewRow.HeaderCell;
}
}
else
{
if (columnIndex >= 0)
{
return this.Columns[columnIndex].HeaderCell;
}
else
{
return this.TopLeftHeaderCell;
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.GetClipboardContent"]/*' />
[
SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes"), // using specialized DataGridViewCellLinkedList class instead of generics
]
public virtual DataObject GetClipboardContent()
{
if (this.ClipboardCopyMode == DataGridViewClipboardCopyMode.Disable)
{
throw new NotSupportedException(SR.GetString(SR.DataGridView_DisabledClipboardCopy));
}
if (this.CurrentCellIsEditedAndOnlySelectedCell)
{
return null;
}
string[] formats = new string[] { DataFormats.Html, DataFormats.Text, DataFormats.UnicodeText, DataFormats.CommaSeparatedValue };
DataObject dataObject = new DataObject();
bool includeColumnHeaders = false, includeRowHeaders = false;
string cellContent = null;
StringBuilder sbContent = null;
DataGridViewColumn dataGridViewColumn, prevDataGridViewColumn, nextDataGridViewColumn;
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullRowSelect:
if (this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected) == 0)
{
return null;
}
if (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableWithAutoHeaderText)
{
includeColumnHeaders = (this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Selected) == -1);
includeRowHeaders = true;
}
else
{
includeColumnHeaders = includeRowHeaders = (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText);
}
includeColumnHeaders &= this.ColumnHeadersVisible;
includeRowHeaders &= this.RowHeadersVisible;
foreach (string format in formats)
{
/* if (!String.Equals(format, DataFormats.Html, StringComparison.OrdinalIgnoreCase) &&
!String.Equals(format, DataFormats.Text, StringComparison.OrdinalIgnoreCase) &&
!String.Equals(format, DataFormats.UnicodeText, StringComparison.OrdinalIgnoreCase) &&
!String.Equals(format, DataFormats.CommaSeparatedValue, StringComparison.OrdinalIgnoreCase))
{
continue;
}*/
if (sbContent == null)
{
sbContent = new StringBuilder(1024);
}
else
{
sbContent.Length = 0;
}
if (includeColumnHeaders)
{
if (this.RightToLeftInternal)
{
// Cycle through the visible columns in their reverse display order
dataGridViewColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None);
if (dataGridViewColumn != null)
{
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
true /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
|