|
//------------------------------------------------------------------------------
// <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*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (prevDataGridViewColumn != null)
{
dataGridViewColumn = prevDataGridViewColumn;
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
false /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
if (includeRowHeaders)
{
cellContent = this.TopLeftHeaderCell.GetClipboardContentInternal(-1,
this.Columns.GetColumnCount(DataGridViewElementStates.Visible) == 0 /*firstCell*/,
true /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
else
{
if (includeRowHeaders)
{
cellContent = this.TopLeftHeaderCell.GetClipboardContentInternal(-1,
true /*firstCell*/,
this.Columns.GetColumnCount(DataGridViewElementStates.Visible) == 0 /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
// Cycle through the visible columns in their display order
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
if (dataGridViewColumn != null)
{
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
!includeRowHeaders /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (nextDataGridViewColumn != null)
{
dataGridViewColumn = nextDataGridViewColumn;
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
false /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
}
}
// Cycle through the visible selected rows.
bool firstRowIndex = true;
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected);
Debug.Assert(rowIndex != -1);
int nextRowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected);
while (rowIndex != -1)
{
if (this.RightToLeftInternal)
{
dataGridViewColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None);
// Cycle through the visible columns in their reverse display order
if (dataGridViewColumn != null)
{
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
true /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (prevDataGridViewColumn != null)
{
dataGridViewColumn = prevDataGridViewColumn;
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
false /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
// Get the row header clipboard content
if (includeRowHeaders)
{
cellContent = this.Rows.SharedRow(rowIndex).HeaderCell.GetClipboardContentInternal(rowIndex,
this.Columns.GetColumnCount(DataGridViewElementStates.Visible) == 0 /*firstCell*/,
true /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
else
{
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
// Get the row header clipboard content
if (includeRowHeaders)
{
cellContent = this.Rows.SharedRow(rowIndex).HeaderCell.GetClipboardContentInternal(rowIndex,
true /*firstCell*/,
dataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
// Cycle through the visible columns in their display order
if (dataGridViewColumn != null)
{
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
!includeRowHeaders /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (nextDataGridViewColumn != null)
{
dataGridViewColumn = nextDataGridViewColumn;
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
false /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
}
rowIndex = nextRowIndex;
if (rowIndex != -1)
{
nextRowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected);
}
firstRowIndex = false;
}
if (String.Equals(format, DataFormats.Html, StringComparison.OrdinalIgnoreCase))
{
System.IO.MemoryStream utf8Stream = null;
GetClipboardContentForHtml(sbContent, out utf8Stream);
dataObject.SetData(format, false /*autoConvert*/, utf8Stream);
}
else
{
dataObject.SetData(format, false /*autoConvert*/, sbContent.ToString());
}
}
break;
case DataGridViewSelectionMode.FullColumnSelect:
if (this.Columns.GetColumnCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected) == 0)
{
return null;
}
if (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableWithAutoHeaderText)
{
includeColumnHeaders = true;
includeRowHeaders = (this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Selected) == null);
}
else
{
includeColumnHeaders = includeRowHeaders = (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText);
}
includeColumnHeaders &= this.ColumnHeadersVisible;
includeRowHeaders &= this.RowHeadersVisible;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
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 & selected columns in their display order
DataGridViewColumn lastDataGridViewColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
dataGridViewColumn = lastDataGridViewColumn;
Debug.Assert(dataGridViewColumn != null);
if (dataGridViewColumn != null)
{
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
true /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
firstVisibleRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (prevDataGridViewColumn != null)
{
dataGridViewColumn = prevDataGridViewColumn;
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
false /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
firstVisibleRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
if (includeRowHeaders)
{
cellContent = this.TopLeftHeaderCell.GetClipboardContentInternal(-1,
lastDataGridViewColumn == null /*firstCell*/,
true /*lastCell*/,
true /*inFirstRow*/,
firstVisibleRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
else
{
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected);
if (includeRowHeaders)
{
cellContent = this.TopLeftHeaderCell.GetClipboardContentInternal(-1,
true /*firstCell*/,
dataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
firstVisibleRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
// Cycle through the visible & selected columns in their display order
Debug.Assert(dataGridViewColumn != null);
if (dataGridViewColumn != null)
{
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
!includeRowHeaders /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
firstVisibleRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (nextDataGridViewColumn != null)
{
dataGridViewColumn = nextDataGridViewColumn;
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
false /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
firstVisibleRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
}
}
// Cycle through the visible rows.
bool firstRowIndex = true;
int rowIndex = firstVisibleRowIndex;
int nextRowIndex = -1;
if (rowIndex != -1)
{
nextRowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
while (rowIndex != -1)
{
if (this.RightToLeftInternal)
{
DataGridViewColumn lastDataGridViewColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
// Cycle through the visible & selected columns in their reverse display order
dataGridViewColumn = lastDataGridViewColumn;
if (dataGridViewColumn != null)
{
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
true /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (prevDataGridViewColumn != null)
{
dataGridViewColumn = prevDataGridViewColumn;
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
false /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
// Get the row header clipboard content
if (includeRowHeaders)
{
cellContent = this.Rows.SharedRow(rowIndex).HeaderCell.GetClipboardContentInternal(rowIndex,
lastDataGridViewColumn == null /*firstCell*/,
true /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
else
{
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected);
// Get the row header clipboard content
if (includeRowHeaders)
{
cellContent = this.Rows.SharedRow(rowIndex).HeaderCell.GetClipboardContentInternal(rowIndex,
true /*firstCell*/,
dataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
// Cycle through the visible & selected columns in their display order
if (dataGridViewColumn != null)
{
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
!includeRowHeaders /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
while (nextDataGridViewColumn != null)
{
dataGridViewColumn = nextDataGridViewColumn;
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible | DataGridViewElementStates.Selected, DataGridViewElementStates.None);
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
false /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
}
rowIndex = nextRowIndex;
if (rowIndex != -1)
{
nextRowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
firstRowIndex = false;
}
if (String.Equals(format, DataFormats.Html, StringComparison.OrdinalIgnoreCase))
{
System.IO.MemoryStream utf8Stream = null;
GetClipboardContentForHtml(sbContent, out utf8Stream);
dataObject.SetData(format, false /*autoConvert*/, utf8Stream);
}
else
{
dataObject.SetData(format, false /*autoConvert*/, sbContent.ToString());
}
}
break;
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
bool selectedVisibleCellExists = false;
bool selectedVisibleColumnExists = false;
bool selectedVisibleRowExists = false;
if (this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect)
{
selectedVisibleRowExists = this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected) != 0;
selectedVisibleCellExists = selectedVisibleRowExists && this.Columns.GetColumnCount(DataGridViewElementStates.Visible) != 0;
}
else if (this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect)
{
selectedVisibleColumnExists = this.Columns.GetColumnCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Selected) != 0;
selectedVisibleCellExists = selectedVisibleColumnExists && this.Rows.GetRowCount(DataGridViewElementStates.Visible) != 0;
}
if (!selectedVisibleCellExists && this.individualSelectedCells.Count > 0)
{
foreach (DataGridViewCell dataGridViewCell in this.individualSelectedCells)
{
if (dataGridViewCell.Visible)
{
selectedVisibleCellExists = true;
break;
}
}
}
if (!selectedVisibleCellExists)
{
return null;
}
// There is at least one selected visible cell.
if (this.SelectionMode == DataGridViewSelectionMode.CellSelect)
{
includeColumnHeaders = includeRowHeaders = (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText);
includeColumnHeaders &= this.ColumnHeadersVisible;
includeRowHeaders &= this.RowHeadersVisible;
}
else
{
includeColumnHeaders = includeRowHeaders = false;
if (this.ColumnHeadersVisible)
{
if (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableWithAutoHeaderText)
{
if (selectedVisibleColumnExists)
{
includeColumnHeaders = true;
}
/* Use this code if column headers should be included when all cells are selected in a visible column.
else
{
// Include column headers if there is a column where all visible cells are selected
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
Debug.Assert(dataGridViewColumn != null);
while (dataGridViewColumn != null)
{
// Cycle through the visible rows, see if the cell in that column is selected
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
while (rowIndex != -1)
{
if (!this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].Selected)
{
break;
}
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
if (rowIndex == -1)
{
// All visible cells in column are selected
includeColumnHeaders = true;
break;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
}
*/
}
else
{
includeColumnHeaders = (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText);
}
}
if (this.RowHeadersVisible)
{
if (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableWithAutoHeaderText)
{
if (selectedVisibleRowExists)
{
includeRowHeaders = true;
}
/* Use this code if row headers should be included when all cells are selected in a visible row.
else
{
// Include row headers if there is a row where all visible cells are selected
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
Debug.Assert(rowIndex != -1);
while (rowIndex != -1)
{
// Cycle through the visible columns, see if the cell in that row is selected
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
Debug.Assert(dataGridViewColumn != null);
while (dataGridViewColumn != null)
{
if (!this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].Selected)
{
break;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
if (dataGridViewColumn == null)
{
// All visible cells in row are selected
includeRowHeaders = true;
break;
}
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
}
*/
}
else
{
includeRowHeaders = (clipboardCopyMode == DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText);
}
}
}
// Get the four corners of the 'selected table'
int lRowIndex = int.MaxValue;
int uRowIndex = -1;
DataGridViewColumn lColumn = null, uColumn = null;
if (this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect)
{
DataGridViewColumn firstVisibleColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
DataGridViewColumn lastVisibleColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(firstVisibleColumn != null);
Debug.Assert(lastVisibleColumn != null);
foreach (int rowIndex in this.selectedBandIndexes)
{
if ((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) != 0)
{
if (rowIndex < lRowIndex)
{
lRowIndex = rowIndex;
}
if (rowIndex > uRowIndex)
{
uRowIndex = rowIndex;
}
lColumn = firstVisibleColumn;
uColumn = lastVisibleColumn;
}
}
}
else if (this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect)
{
firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
Debug.Assert(firstVisibleRowIndex != -1);
Debug.Assert(lastVisibleRowIndex != -1);
foreach (int columnIndex in this.selectedBandIndexes)
{
if (this.Columns[columnIndex].Visible)
{
if (lColumn == null || this.Columns.DisplayInOrder(columnIndex, lColumn.Index))
{
lColumn = this.Columns[columnIndex];
}
if (uColumn == null || this.Columns.DisplayInOrder(uColumn.Index, columnIndex))
{
uColumn = this.Columns[columnIndex];
}
lRowIndex = firstVisibleRowIndex;
uRowIndex = lastVisibleRowIndex;
}
}
}
// Go through the individually selected cells to potentially stretch the current 'selected table'.
foreach (DataGridViewCell dataGridViewCell in this.individualSelectedCells)
{
if (dataGridViewCell.Visible)
{
if (dataGridViewCell.RowIndex < lRowIndex)
{
lRowIndex = dataGridViewCell.RowIndex;
}
if (dataGridViewCell.RowIndex > uRowIndex)
{
uRowIndex = dataGridViewCell.RowIndex;
}
if (lColumn == null || this.Columns.DisplayInOrder(dataGridViewCell.ColumnIndex, lColumn.Index))
{
lColumn = dataGridViewCell.OwningColumn;
}
if (uColumn == null || this.Columns.DisplayInOrder(uColumn.Index, dataGridViewCell.ColumnIndex))
{
uColumn = dataGridViewCell.OwningColumn;
}
}
}
Debug.Assert(lRowIndex != -1);
Debug.Assert(uRowIndex != -1);
Debug.Assert(lColumn != null);
Debug.Assert(uColumn != null);
Debug.Assert(lColumn.Index == uColumn.Index || this.Columns.DisplayInOrder(lColumn.Index, uColumn.Index));
Debug.Assert(lRowIndex <= uRowIndex);
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 from uColumn to lColumn
dataGridViewColumn = uColumn;
Debug.Assert(dataGridViewColumn != null);
while (dataGridViewColumn != null)
{
if (dataGridViewColumn != lColumn)
{
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(prevDataGridViewColumn != null);
}
else
{
prevDataGridViewColumn = null;
}
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
dataGridViewColumn == uColumn /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
dataGridViewColumn = prevDataGridViewColumn;
}
if (includeRowHeaders)
{
cellContent = this.TopLeftHeaderCell.GetClipboardContentInternal(-1,
false /*firstCell*/,
true /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
else
{
if (includeRowHeaders)
{
cellContent = this.TopLeftHeaderCell.GetClipboardContentInternal(-1,
true /*firstCell*/,
false /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
// Cycle through the visible columns from lColumn to uColumn
dataGridViewColumn = lColumn;
Debug.Assert(dataGridViewColumn != null);
while (dataGridViewColumn != null)
{
if (dataGridViewColumn != uColumn)
{
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(nextDataGridViewColumn != null);
}
else
{
nextDataGridViewColumn = null;
}
cellContent = dataGridViewColumn.HeaderCell.GetClipboardContentInternal(-1,
!includeRowHeaders && dataGridViewColumn == lColumn /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
true /*inFirstRow*/,
false /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
dataGridViewColumn = nextDataGridViewColumn;
}
}
}
// Cycle through the visible rows from lRowIndex to uRowIndex.
bool firstRowIndex = true;
int rowIndex = lRowIndex;
int nextRowIndex = -1;
Debug.Assert(rowIndex != -1);
while (rowIndex != -1)
{
if (rowIndex != uRowIndex)
{
nextRowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
Debug.Assert(nextRowIndex != -1);
}
else
{
nextRowIndex = -1;
}
if (this.RightToLeftInternal)
{
// Cycle through the visible columns from uColumn to lColumn
dataGridViewColumn = uColumn;
Debug.Assert(dataGridViewColumn != null);
while (dataGridViewColumn != null)
{
if (dataGridViewColumn != lColumn)
{
prevDataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(prevDataGridViewColumn != null);
}
else
{
prevDataGridViewColumn = null;
}
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
dataGridViewColumn == uColumn /*firstCell*/,
!includeRowHeaders && prevDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
dataGridViewColumn = prevDataGridViewColumn;
}
if (includeRowHeaders)
{
// Get the row header clipboard content
cellContent = this.Rows.SharedRow(rowIndex).HeaderCell.GetClipboardContentInternal(rowIndex,
false /*firstCell*/,
true /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
}
else
{
if (includeRowHeaders)
{
// Get the row header clipboard content
cellContent = this.Rows.SharedRow(rowIndex).HeaderCell.GetClipboardContentInternal(rowIndex,
true /*firstCell*/,
false /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
}
// Cycle through the visible columns from lColumn to uColumn
dataGridViewColumn = lColumn;
Debug.Assert(dataGridViewColumn != null);
while (dataGridViewColumn != null)
{
if (dataGridViewColumn != uColumn)
{
nextDataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(nextDataGridViewColumn != null);
}
else
{
nextDataGridViewColumn = null;
}
cellContent = this.Rows.SharedRow(rowIndex).Cells[dataGridViewColumn.Index].GetClipboardContentInternal(rowIndex,
!includeRowHeaders && dataGridViewColumn == lColumn /*firstCell*/,
nextDataGridViewColumn == null /*lastCell*/,
!includeColumnHeaders && firstRowIndex /*inFirstRow*/,
nextRowIndex == -1 /*inLastRow*/,
format) as string;
if (cellContent != null)
{
sbContent.Append(cellContent);
}
dataGridViewColumn = nextDataGridViewColumn;
}
}
rowIndex = nextRowIndex;
firstRowIndex = false;
}
if (String.Equals(format, DataFormats.Html, StringComparison.OrdinalIgnoreCase))
{
System.IO.MemoryStream utf8Stream = null;
GetClipboardContentForHtml(sbContent, out utf8Stream);
dataObject.SetData(format, false /*autoConvert*/, utf8Stream);
}
else
{
dataObject.SetData(format, false /*autoConvert*/, sbContent.ToString());
}
}
break;
}
return dataObject;
}
private static void GetClipboardContentForHtml(StringBuilder sbContent, out System.IO.MemoryStream utf8Stream)
{
byte[] sourceBytes = Encoding.Unicode.GetBytes(sbContent.ToString());
byte[] destinationBytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, sourceBytes);
// Marshal.SystemDefaultCharSize is 2 on WinXP Pro - so the offsets seem to be in character counts instead of bytes.
// Test on JPN and Win9x machines.
int bytecountEndOfFragment = 135 + destinationBytes.Length;
int bytecountEndOfHtml = bytecountEndOfFragment + 36;
string prefix = string.Format(CultureInfo.InvariantCulture, DATAGRIDVIEW_htmlPrefix, bytecountEndOfHtml.ToString("00000000", CultureInfo.InvariantCulture), bytecountEndOfFragment.ToString("00000000", CultureInfo.InvariantCulture)) + DATAGRIDVIEW_htmlStartFragment;
sbContent.Insert(0, prefix);
sbContent.Append(DATAGRIDVIEW_htmlEndFragment);
sourceBytes = Encoding.Unicode.GetBytes(sbContent.ToString());
destinationBytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, sourceBytes);
utf8Stream = new System.IO.MemoryStream(bytecountEndOfHtml + 1);
utf8Stream.Write(destinationBytes, 0, bytecountEndOfHtml);
utf8Stream.WriteByte((byte)0);
#if DEBUG
Debug.Assert(destinationBytes[97] == '<');
Debug.Assert(destinationBytes[bytecountEndOfHtml-1] == '>');
Debug.Assert(destinationBytes[133] == '<');
Debug.Assert(destinationBytes[bytecountEndOfFragment] == '<');
#endif
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.GetColumnDisplayRectangle"]/*' />
// Rectangle returned includes the potential column header
public Rectangle GetColumnDisplayRectangle(int columnIndex, bool cutOverflow)
{
if (columnIndex < 0 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
return GetColumnDisplayRectanglePrivate(columnIndex, cutOverflow);
}
private Rectangle GetColumnDisplayRectanglePrivate(int columnIndex, bool cutOverflow)
{
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count);
if (!this.Columns[columnIndex].Displayed)
{
return Rectangle.Empty;
}
Rectangle data = this.layout.Data;
int cx;
bool columnFound = false;
DataGridViewColumn dataGridViewColumn;
if (this.RightToLeftInternal)
{
cx = data.Right;
}
else
{
cx = data.X;
}
for (dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
dataGridViewColumn != null && !columnFound;
)
{
if ((this.RightToLeftInternal && cx < data.X) ||
(!this.RightToLeftInternal && cx > data.Right))
{
break;
}
if (dataGridViewColumn.Index == columnIndex)
{
columnFound = true;
}
else
{
if (this.RightToLeftInternal)
{
cx -= dataGridViewColumn.Thickness;
}
else
{
cx += dataGridViewColumn.Thickness;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen,
DataGridViewElementStates.None);
}
}
if (!columnFound && this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0)
{
for (dataGridViewColumn = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
dataGridViewColumn != null && !columnFound;
)
{
if ((this.RightToLeftInternal && cx < data.X) ||
(!this.RightToLeftInternal && cx > data.Right))
{
break;
}
if (dataGridViewColumn.Index == columnIndex)
{
columnFound = true;
}
else
{
if (this.RightToLeftInternal)
{
cx -= dataGridViewColumn.Thickness;
}
else
{
cx += dataGridViewColumn.Thickness;
}
if (dataGridViewColumn.Index == this.displayedBandsInfo.FirstDisplayedScrollingCol)
{
if (this.RightToLeftInternal)
{
cx += this.negOffset;
}
else
{
cx -= this.negOffset;
}
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
}
}
if (columnFound)
{
Debug.Assert(dataGridViewColumn != null);
int displayWidth, viewedColumnWidth = dataGridViewColumn.Thickness;
if (dataGridViewColumn.Index == this.displayedBandsInfo.FirstDisplayedScrollingCol)
{
viewedColumnWidth -= this.negOffset;
}
if (cutOverflow &&
((!this.RightToLeftInternal && cx + viewedColumnWidth > data.Right) ||
(this.RightToLeftInternal && cx - viewedColumnWidth < data.X)))
{
if (this.RightToLeftInternal)
{
displayWidth = cx - data.X;
}
else
{
displayWidth = data.Right - cx;
}
}
else
{
displayWidth = viewedColumnWidth;
}
Rectangle columnRect;
if (this.RightToLeftInternal)
{
columnRect = new Rectangle(cx - displayWidth, data.Y, displayWidth, data.Height);
}
else
{
columnRect = new Rectangle(cx, data.Y, displayWidth, data.Height);
}
if (this.layout.ColumnHeadersVisible)
{
columnRect.Height += this.layout.ColumnHeaders.Height;
columnRect.Y -= this.layout.ColumnHeaders.Height;
}
return columnRect;
}
return Rectangle.Empty;
}
// xColumnLeftEdge returns the left edge of the column when RightToLeft is false.
// xColumnLeftEdge returns the right edge of the column when RightToLeft is true.
private int GetColumnIndexFromX(int x, out int xColumnLeftEdge)
{
Rectangle data = this.layout.Data;
Debug.Assert(this.RightToLeftInternal || (x >= data.X - 1 && x < data.Right), "x must be inside the horizontal bounds of this.layout.Data");
Debug.Assert(!this.RightToLeftInternal || (x >= data.X && x <= data.Right), "x must be inside the horizontal bounds of this.layout.Data");
if (!this.RightToLeftInternal && x == data.X - 1)
{
x++;
}
else if (this.RightToLeftInternal && x == data.Right)
{
x--;
}
int cx;
if (this.RightToLeftInternal)
{
cx = data.Right-1;
}
else
{
cx = data.X;
}
// first try to match x against a frozen column
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (dataGridViewColumn != null &&
((!this.RightToLeftInternal && cx < data.Right) || (this.RightToLeftInternal && cx >= data.X)))
{
if (this.RightToLeftInternal)
{
cx -= dataGridViewColumn.Thickness;
}
else
{
cx += dataGridViewColumn.Thickness;
}
if (!this.RightToLeftInternal && cx > x)
{
xColumnLeftEdge = cx - dataGridViewColumn.Thickness;
return dataGridViewColumn.Index;
}
else if (this.RightToLeftInternal && cx < x)
{
xColumnLeftEdge = cx + dataGridViewColumn.Thickness;
return dataGridViewColumn.Index;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen,
DataGridViewElementStates.None);
}
if (this.RightToLeftInternal)
{
cx += this.negOffset;
}
else
{
cx -= this.negOffset;
}
// second try to match x against a scrolling column
if (this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0)
{
dataGridViewColumn = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
while (dataGridViewColumn != null &&
((!this.RightToLeftInternal && cx < data.Right) || (this.RightToLeftInternal && cx >= data.X)))
{
Debug.Assert(dataGridViewColumn.Visible && !dataGridViewColumn.Frozen);
if (this.RightToLeftInternal)
{
cx -= dataGridViewColumn.Thickness;
}
else
{
cx += dataGridViewColumn.Thickness;
}
if (!this.RightToLeftInternal && cx > x)
{
xColumnLeftEdge = cx - dataGridViewColumn.Thickness;
return dataGridViewColumn.Index;
}
else if (this.RightToLeftInternal && cx < x)
{
xColumnLeftEdge = cx + dataGridViewColumn.Thickness;
return dataGridViewColumn.Index;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
}
xColumnLeftEdge = -1;
return -1;
}
private static int GetColumnScrollRate(int xOffset)
{
Debug.Assert(xOffset > 0);
// Counting 20ms for executing the actual column scrolling
if (xOffset <= 10)
{
return 480; // Two columns per second
}
if (xOffset <= 15)
{
return 313; // Three columns per second
}
if (xOffset <= 25)
{
return 180; // Five columns per second
}
if (xOffset <= 35)
{
return 123; // Seven columns per second
}
return Math.Max(1, 4000 / xOffset);
}
/// <devdoc>
/// Returns the coordinate of the left edge of the given column. Note that
/// the column does not need to be completely visible on the display area.
/// Value returned is not necessarily within layout.Data because of the
/// this.negOffset value, or because the column may start to the right of
/// data area, or behind the frozen area, or completely on the left of the control.
/// The right edge is returned in RightToLeft mode.
/// </devdoc>
internal int GetColumnXFromIndex(int index)
{
Debug.Assert(index < this.Columns.Count);
Debug.Assert(this.Columns[index].Visible);
int x;
if (this.RightToLeftInternal)
{
x = this.layout.Data.Right-1;
}
else
{
x = this.layout.Data.X;
}
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (dataGridViewColumn != null)
{
if (index == dataGridViewColumn.Index)
{
return x;
}
if (this.RightToLeftInternal)
{
x -= dataGridViewColumn.Thickness;
}
else
{
x += dataGridViewColumn.Thickness;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen,
DataGridViewElementStates.None);
}
if (this.RightToLeftInternal)
{
x += this.negOffset;
}
else
{
x -= this.negOffset;
}
int xFirstVisibleScrollingCol = x;
if (this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0)
{
dataGridViewColumn = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
}
else
{
dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
}
Debug.Assert(dataGridViewColumn.Visible && !dataGridViewColumn.Frozen);
while (dataGridViewColumn != null)
{
if (index == dataGridViewColumn.Index)
{
return x;
}
if (this.RightToLeftInternal)
{
x -= dataGridViewColumn.Thickness;
}
else
{
x += dataGridViewColumn.Thickness;
}
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
// The column is completely hidden on the left/right of the dataGridView
x = xFirstVisibleScrollingCol;
dataGridViewColumn = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
dataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
while (dataGridViewColumn != null)
{
if (this.RightToLeftInternal)
{
x += dataGridViewColumn.Thickness;
}
else
{
x -= dataGridViewColumn.Thickness;
}
if (index == dataGridViewColumn.Index)
{
return x;
}
dataGridViewColumn = this.Columns.GetPreviousColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
}
Debug.Fail("Could not find column in GetColumnXFromIndex");
return 0;
}
private int GetNegOffsetFromHorizontalOffset(int horizontalOffset)
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
while (dataGridViewColumn != null && dataGridViewColumn.Thickness <= horizontalOffset)
{
horizontalOffset -= dataGridViewColumn.Thickness;
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
return horizontalOffset;
}
private bool GetOutOfBoundCorrectedHitTestInfo(ref HitTestInfo hti, ref int mouseX, ref int mouseY, out int xOffset, out int yOffset)
{
xOffset = yOffset = 0;
Rectangle rectScrollingArea = this.layout.Data;
int visibleRowsHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible);
int frozenVisibleRowsHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
int fittingTrailingScrollingRowsHeight = ComputeHeightOfFittingTrailingScrollingRows(frozenVisibleRowsHeight);
int trailingScrollingRowsHeight = ComputeHeightOfTrailingScrollingRows();
int emptyBackgroundWidth = Math.Max(0, this.layout.Data.Width - this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible));
int emptyBackgroundHeight = Math.Max(0, this.layout.Data.Height - frozenVisibleRowsHeight - trailingScrollingRowsHeight);
Debug.Assert(!this.vertScrollBar.Enabled ||
!this.vertScrollBar.Visible ||
this.vertScrollBar.Maximum == visibleRowsHeight - frozenVisibleRowsHeight);
//VSWhidbey 525671
//Debug.Assert(!this.vertScrollBar.Enabled ||
// !this.vertScrollBar.Visible ||
// this.vertScrollBar.Value >= this.verticalOffset);
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect])
{
if (this.layout.RowHeadersVisible)
{
// Include row headers
rectScrollingArea = Rectangle.Union(rectScrollingArea, this.layout.RowHeaders);
}
// Discard frozen rows
DiscardZonesInScrollingArea(ref rectScrollingArea, emptyBackgroundWidth, emptyBackgroundHeight, frozenVisibleRowsHeight,
false /*discardFrozenColumns*/, true /*discardFrozenRows*/);
if (mouseY >= rectScrollingArea.Top && mouseY <= rectScrollingArea.Bottom)
{
// Mouse's Y is in-bound -- correct X value
hti = HitTest(this.RightToLeftInternal ? rectScrollingArea.Right-1 : rectScrollingArea.Left, mouseY);
if (this.ptAnchorCell.Y != -1 &&
(this.Rows.GetRowState(this.ptAnchorCell.Y) & DataGridViewElementStates.Frozen) != 0 &&
this.trackRowEdge != -1 &&
(this.Rows.GetRowState(this.trackRowEdge) & DataGridViewElementStates.Frozen) != 0 &&
hti.row >= 0 &&
(this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Frozen) == 0)
{
// Anchor cell is in frozen row and target cell is in unfrozen row. Make sure no row is scrolled off.
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
int firstUnfrozenRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
int firstColumnIndex;
if (hti.col >= 0)
{
firstColumnIndex = hti.col;
}
else
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
firstColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
}
if (firstColumnIndex >= 0 && firstUnfrozenRowIndex >= 0)
{
if (!ScrollIntoView(firstColumnIndex, firstUnfrozenRowIndex, false /*forCurrentCellChange*/))
{
return false;
}
hti = HitTest(this.RightToLeftInternal ? rectScrollingArea.Right : rectScrollingArea.Left, mouseY);
}
}
return true;
}
// Mouse's Y is outside of scrolling bands
if (mouseY < rectScrollingArea.Top)
{
if (this.ptAnchorCell.Y != -1 &&
((this.Rows.GetRowState(this.ptAnchorCell.Y) & DataGridViewElementStates.Frozen) == 0 ||
(this.trackRowEdge != -1 && (this.Rows.GetRowState(this.trackRowEdge) & DataGridViewElementStates.Frozen) == 0)) &&
this.verticalOffset != 0)
{
// Up scrolling is required because the anchor's row is unfrozen
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
yOffset = mouseY - rectScrollingArea.Top; // yOffset strictly negative
if (this.RightToLeftInternal)
{
mouseX = rectScrollingArea.Right-1;
}
else
{
mouseX = rectScrollingArea.Left+1;
}
}
else
{
hti = HitTest(this.RightToLeftInternal ? rectScrollingArea.Right : rectScrollingArea.Left, mouseY);
}
}
else
{
Debug.Assert(mouseY > rectScrollingArea.Bottom);
if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0)
{
if (this.verticalOffset + this.Rows.SharedRow(this.displayedBandsInfo.FirstDisplayedScrollingRow).GetHeight(this.displayedBandsInfo.FirstDisplayedScrollingRow) <=
visibleRowsHeight - frozenVisibleRowsHeight - fittingTrailingScrollingRowsHeight)
{
// Down scrolling is required
yOffset = mouseY - rectScrollingArea.Bottom; // yOffset strictly positive
if (this.RightToLeftInternal)
{
mouseX = rectScrollingArea.Right-1;
}
else
{
mouseX = rectScrollingArea.Left+1;
}
}
}
}
return true;
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect])
{
if (this.layout.ColumnHeadersVisible)
{
// Include column headers
rectScrollingArea = Rectangle.Union(rectScrollingArea, this.layout.ColumnHeaders);
}
// Discard frozen columns
DiscardZonesInScrollingArea(ref rectScrollingArea, emptyBackgroundWidth, emptyBackgroundHeight, frozenVisibleRowsHeight,
true /*discardFrozenColumns*/, false /*discardFrozenRows*/);
if (mouseX >= rectScrollingArea.Left && mouseX <= rectScrollingArea.Right)
{
// Mouse's X is in-bound -- correct Y value
hti = HitTest(mouseX, rectScrollingArea.Top);
if (this.ptAnchorCell.X != -1 &&
this.Columns[this.ptAnchorCell.X].Frozen &&
this.trackColumnEdge != -1 &&
this.Columns[this.trackColumnEdge].Frozen &&
hti.col >= 0 &&
!this.Columns[hti.col].Frozen)
{
// Anchor cell is in frozen column and target cell is in unfrozen column. Make sure no column is scrolled off.
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0);
int firstUnfrozenColumnIndex = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen).Index;
int firstRowIndex;
if (hti.row >= 0)
{
firstRowIndex = hti.row;
}
else
{
firstRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
}
if (firstRowIndex >= 0 && firstUnfrozenColumnIndex >= 0)
{
if (!ScrollIntoView(firstUnfrozenColumnIndex, firstRowIndex, false /*forCurrentCellChange*/))
{
return false;
}
hti = HitTest(mouseX, rectScrollingArea.Top);
}
}
return true;
}
// Mouse's X is outside of scrolling bands
if ((!this.RightToLeftInternal && mouseX < rectScrollingArea.Left) ||
(this.RightToLeftInternal && mouseX > rectScrollingArea.Right))
{
if (this.ptAnchorCell.X != -1 &&
(!this.Columns[this.ptAnchorCell.X].Frozen ||
(this.trackColumnEdge != -1 && !this.Columns[this.trackColumnEdge].Frozen)) &&
this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0 &&
(this.negOffset > 0 ||
this.Columns.GetPreviousColumn(this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol], DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen) != null))
{
// xOffset strictly negative
if (this.RightToLeftInternal)
{
// Right scrolling is required
xOffset = rectScrollingArea.Right - mouseX;
}
else
{
// Left scrolling is required
xOffset = mouseX - rectScrollingArea.Left;
}
mouseY = rectScrollingArea.Top+1;
}
else
{
hti = HitTest(mouseX, rectScrollingArea.Top);
}
}
else
{
Debug.Assert((!this.RightToLeftInternal && mouseX > rectScrollingArea.Right) || (this.RightToLeftInternal && mouseX < rectScrollingArea.Left));
if (this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0)
{
if (this.displayedBandsInfo.LastTotallyDisplayedScrollingCol != -1 &&
this.Columns.GetNextColumn(this.Columns[this.displayedBandsInfo.LastTotallyDisplayedScrollingCol], DataGridViewElementStates.Visible, DataGridViewElementStates.None) == null)
{
// No more columns to scroll
return true;
}
DataGridViewColumn newFirstVisibleScrollingCol = this.Columns.GetNextColumn(this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
int newColOffset = 0;
for (DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
dataGridViewColumn != newFirstVisibleScrollingCol;
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None))
{
newColOffset += dataGridViewColumn.Thickness;
}
if (this.HorizontalOffset != newColOffset)
{
// xOffset strictly positive
if (this.RightToLeftInternal)
{
// Left scrolling is required
xOffset = rectScrollingArea.Left - mouseX;
}
else
{
// Right scrolling is required
xOffset = mouseX - rectScrollingArea.Right;
}
mouseY = rectScrollingArea.Top+1;
}
}
}
return true;
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect])
{
bool recomputeHitTestInfo = false;
// Discard frozen columns and rows
DiscardZonesInScrollingArea(ref rectScrollingArea, emptyBackgroundWidth, emptyBackgroundHeight, frozenVisibleRowsHeight,
true /*discardFrozenColumns*/, true /*discardFrozenRows*/);
if (mouseY < rectScrollingArea.Top)
{
// Mouse's Y is above scrolling bands
if (
(
(this.ptAnchorCell.Y != -1 && (this.Rows.GetRowState(this.ptAnchorCell.Y) & DataGridViewElementStates.Frozen) == 0)
||
(this.ptCurrentCell.Y != -1 && (this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Frozen) == 0)
)
&&
this.verticalOffset != 0
)
{
// Up scrolling is required - the anchor's row is unfrozen
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
yOffset = mouseY - rectScrollingArea.Top; // yOffset strictly negative
}
else
{
// Correct mouse's Y - no scrolling can be performed
if (mouseY < this.layout.Data.Top)
{
mouseY = this.layout.Data.Top+1;
recomputeHitTestInfo = true;
}
}
}
else if (mouseY > rectScrollingArea.Bottom)
{
// Mouse's Y is below scrolling bands
if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0)
{
if (this.verticalOffset + this.Rows.SharedRow(this.displayedBandsInfo.FirstDisplayedScrollingRow).GetHeight(this.displayedBandsInfo.FirstDisplayedScrollingRow) <=
visibleRowsHeight - frozenVisibleRowsHeight - fittingTrailingScrollingRowsHeight)
{
// Down scrolling is required
yOffset = mouseY - rectScrollingArea.Bottom; // yOffset strictly positive
}
else
{
// Correct mouse's Y - no scrolling can be performed
mouseY = rectScrollingArea.Bottom-1;
recomputeHitTestInfo = true;
}
}
else
{
// Correct mouse's Y - no scrolling can be performed
mouseY = rectScrollingArea.Bottom-1;
recomputeHitTestInfo = true;
}
}
#if DEBUG
else
{
// Mouse's Y is in-bound
Debug.Assert(mouseY >= rectScrollingArea.Top && mouseY <= rectScrollingArea.Bottom);
}
#endif
if ((!this.RightToLeftInternal && mouseX < rectScrollingArea.Left) ||
(this.RightToLeftInternal && mouseX > rectScrollingArea.Right))
{
// Mouse's X is on the left of scrolling bands (LTR)
if (
(
(this.ptAnchorCell.X != -1 && !this.Columns[this.ptAnchorCell.X].Frozen)
||
(this.ptCurrentCell.X != -1 && !this.Columns[this.ptCurrentCell.X].Frozen)
)
&&
this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0 &&
(this.negOffset > 0 ||
this.Columns.GetPreviousColumn(this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol], DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen) != null)
)
{
// xOffset strictly negative
if (this.RightToLeftInternal)
{
// Right scrolling is required - anchor's column is unfrozen
xOffset = rectScrollingArea.Right - mouseX;
}
else
{
// Left scrolling is required - anchor's column is unfrozen
xOffset = mouseX - rectScrollingArea.Left;
}
}
else
{
// Correct mouse's X - no scrolling can be performed
if (!this.RightToLeftInternal && mouseX < this.layout.Data.Left)
{
mouseX = this.layout.Data.Left+1;
recomputeHitTestInfo = true;
}
else if (this.RightToLeftInternal && mouseX > this.layout.Data.Right)
{
mouseX = this.layout.Data.Right-1;
recomputeHitTestInfo = true;
}
}
}
else if ((!this.RightToLeftInternal && mouseX > rectScrollingArea.Right) ||
(this.RightToLeftInternal && mouseX < rectScrollingArea.Left))
{
// Mouse's X is on the right of scrolling bands (LTR)
if (this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0 &&
(this.displayedBandsInfo.LastTotallyDisplayedScrollingCol == -1 ||
this.Columns.GetNextColumn(this.Columns[this.displayedBandsInfo.LastTotallyDisplayedScrollingCol], DataGridViewElementStates.Visible, DataGridViewElementStates.None) != null))
{
DataGridViewColumn newFirstVisibleScrollingCol = this.Columns.GetNextColumn(this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
int newColOffset = 0;
for (DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
dataGridViewColumn != newFirstVisibleScrollingCol;
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None))
{
newColOffset += dataGridViewColumn.Thickness;
}
if (this.HorizontalOffset != newColOffset)
{
// xOffset strictly positive
if (this.RightToLeftInternal)
{
// Left scrolling is required
xOffset = rectScrollingArea.Left - mouseX;
}
else
{
// Right scrolling is required
xOffset = mouseX - rectScrollingArea.Right;
}
}
else
{
// Correct mouse's X - no scrolling can be performed
if (this.RightToLeftInternal)
{
mouseX = rectScrollingArea.Left+1;
}
else
{
mouseX = rectScrollingArea.Right-1;
}
recomputeHitTestInfo = true;
}
}
else
{
// Correct mouse's X - no scrolling can be performed
if (this.RightToLeftInternal)
{
mouseX = rectScrollingArea.Left+1;
}
else
{
mouseX = rectScrollingArea.Right-1;
}
recomputeHitTestInfo = true;
}
}
#if DEBUG
else
{
// Mouse's X is in-bound
Debug.Assert(mouseX >= rectScrollingArea.Left && mouseX <= rectScrollingArea.Right);
}
#endif
if (recomputeHitTestInfo)
{
hti = HitTest(mouseX, mouseY);
}
}
return true;
}
internal override Size GetPreferredSizeCore(Size proposedConstraints)
{
int bordersAndPaddingWidth = 2*(this.BorderWidth + this.Padding.Size.Width);
int bordersAndPaddingHeight = 2*(this.BorderWidth + this.Padding.Size.Height);
bool allowHorizScrollbar = (this.scrollBars == ScrollBars.Both) || (this.scrollBars == ScrollBars.Horizontal);
bool allowVertScrollbar = (this.scrollBars == ScrollBars.Both) || (this.scrollBars == ScrollBars.Vertical);
int minimumWidth = 16 + bordersAndPaddingWidth;
if (allowVertScrollbar)
{
minimumWidth += this.vertScrollBar.Width;
}
if (this.RowHeadersVisible)
{
minimumWidth += this.RowHeadersWidth;
}
int preferredWidth = Math.Min(minimumWidth + this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible), proposedConstraints.Width);
if (preferredWidth < minimumWidth)
{
preferredWidth = minimumWidth;
}
int minimumHeight = 16 + bordersAndPaddingHeight;
if (allowHorizScrollbar)
{
minimumHeight += this.horizScrollBar.Height;
}
if (this.ColumnHeadersVisible)
{
minimumHeight += this.ColumnHeadersHeight;
}
int preferredHeight = Math.Min(minimumHeight + this.Rows.GetRowsHeight(DataGridViewElementStates.Visible), proposedConstraints.Height);
if (preferredHeight < minimumHeight)
{
preferredHeight = minimumHeight;
}
return new Size(preferredWidth, preferredHeight);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.GetRowDisplayRectangle"]/*' />
// Rectangle returned includes the potential row header
public Rectangle GetRowDisplayRectangle(int rowIndex, bool cutOverflow)
{
if (rowIndex < 0 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
return GetRowDisplayRectanglePrivate(rowIndex, cutOverflow);
}
private Rectangle GetRowDisplayRectanglePrivate(int rowIndex, bool cutOverflow)
{
Debug.Assert(rowIndex >= 0 && rowIndex < this.Rows.Count);
if ((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Displayed) == 0)
{
return Rectangle.Empty;
}
Rectangle data = this.layout.Data;
int cy = data.Y;
bool rowFound = false;
int indexTmp;
for (indexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
indexTmp != -1 && !rowFound;
)
{
if (cy > data.Bottom)
{
break;
}
if (indexTmp == rowIndex)
{
rowFound = true;
}
else
{
cy += this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
indexTmp = this.Rows.GetNextRow(indexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
}
if (!rowFound && this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0)
{
for (indexTmp = this.displayedBandsInfo.FirstDisplayedScrollingRow;
indexTmp != -1 && !rowFound;
)
{
if (cy > data.Bottom)
{
break;
}
if (indexTmp == rowIndex)
{
rowFound = true;
}
else
{
cy += this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
indexTmp = this.Rows.GetNextRow(indexTmp, DataGridViewElementStates.Visible);
}
}
}
if (rowFound)
{
int displayHeight;
if (cutOverflow && cy + this.Rows.SharedRow(indexTmp).GetHeight(indexTmp) > data.Bottom)
{
displayHeight = data.Bottom - cy;
}
else
{
displayHeight = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
}
Rectangle rowRect = new Rectangle(data.X,
cy,
data.Width,
displayHeight);
if (this.layout.RowHeadersVisible)
{
rowRect.Width += this.layout.RowHeaders.Width;
if (!this.RightToLeftInternal)
{
rowRect.X -= this.layout.RowHeaders.Width;
}
}
return rowRect;
}
return Rectangle.Empty;
}
private int GetRowIndexFromY(int y, out int yRowTopEdge)
{
Rectangle data = this.layout.Data;
Debug.Assert(y >= data.Y-1 && y < data.Bottom, "y must be inside the vertical bounds of the data area.");
if (y == data.Y-1)
{
y++;
}
int rowHeight;
int cy = data.Y;
// first try to match y against a frozen rows
int indexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (indexTmp != -1 && cy < data.Bottom)
{
rowHeight = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
cy += rowHeight;
if (cy > y)
{
yRowTopEdge = cy - rowHeight;
return indexTmp;
}
indexTmp = this.Rows.GetNextRow(indexTmp,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
// second try to match y against a scrolling row
if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0)
{
indexTmp = this.displayedBandsInfo.FirstDisplayedScrollingRow;
Debug.Assert((this.Rows.GetRowState(indexTmp) & DataGridViewElementStates.Visible) != 0 &&
(this.Rows.GetRowState(indexTmp) & DataGridViewElementStates.Frozen) == 0);
while (indexTmp != -1 && cy < data.Bottom)
{
rowHeight = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
cy += rowHeight;
if (cy > y)
{
yRowTopEdge = cy - rowHeight;
return indexTmp;
}
indexTmp = this.Rows.GetNextRow(indexTmp,
DataGridViewElementStates.Visible);
}
}
yRowTopEdge = -1;
return -1;
}
private static int GetRowScrollRate(int yOffset)
{
Debug.Assert(yOffset > 0);
// Counting 10ms for executing the actual row scrolling
if (yOffset <= 10)
{
return 90; // Ten rows per second
}
if (yOffset <= 15)
{
return 57; // Fifteen rows per second
}
if (yOffset <= 25)
{
return 30; // Twenty-five rows per second
}
if (yOffset <= 35)
{
return 18; // Thirty-five rows per second
}
return Math.Max(1, 600 / yOffset);
}
/// <devdoc>
/// Returns the coordinate of the upper edge of the given row. Note that
/// the row does not need to be completely visible on the display area.
/// Value returned is not necessarily within layout.Data because the row
/// may start below the data area.
/// </devdoc>
internal int GetRowYFromIndex(int index)
{
Debug.Assert(index >= 0 && index < this.Rows.Count);
Debug.Assert((this.Rows.GetRowState(index) & DataGridViewElementStates.Visible) != 0);
int y = this.layout.Data.Y;
int indexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (indexTmp != -1)
{
if (index == indexTmp)
{
return y;
}
y += this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
indexTmp = this.Rows.GetNextRow(indexTmp,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
int yFirstVisibleScrollingRow = y;
if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0)
{
if (index >= this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
// index is part of the scrolling rows below the frozen rows
indexTmp = this.displayedBandsInfo.FirstDisplayedScrollingRow;
}
else
{
// index is part of the rows hidden behind the frozen rows or on top of the control
indexTmp = -1;
}
}
else
{
// frozen rows cover all the rows real-estate. Look for index starting at the first visible non-frozen row.
indexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
Debug.Assert(indexTmp != -1);
}
if (indexTmp != -1)
{
Debug.Assert((this.Rows.GetRowState(indexTmp) & DataGridViewElementStates.Visible) != 0 &&
(this.Rows.GetRowState(indexTmp) & DataGridViewElementStates.Frozen) == 0);
while (indexTmp != -1)
{
if (index == indexTmp)
{
return y;
}
y += this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
indexTmp = this.Rows.GetNextRow(indexTmp, DataGridViewElementStates.Visible);
}
}
// Row is completely hidden behind frozen rows or on top of control
y = yFirstVisibleScrollingRow;
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow != -1);
indexTmp = this.Rows.GetPreviousRow(this.displayedBandsInfo.FirstDisplayedScrollingRow,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
while (indexTmp != -1)
{
y -= this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
if (index == indexTmp)
{
return y;
}
indexTmp = this.Rows.GetPreviousRow(indexTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
}
Debug.Fail("Could not find row in GetRowYFromIndex");
return 0;
}
private bool GetTabKeyEffective(bool shift, bool ctrl)
{
if (this.StandardTab)
{
return ctrl &&
!((!shift && (!this.VisibleCellExists || this.CurrentCellIsLastVisibleCell)) ||
(shift && (!this.VisibleCellExists || this.CurrentCellIsFirstVisibleCell)));
}
else
{
return !ctrl &&
!((!shift && (!this.VisibleCellExists || this.CurrentCellIsLastVisibleCell)) ||
(shift && (!this.VisibleCellExists || this.CurrentCellIsFirstVisibleCell)));
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.HitTest"]/*' />
public HitTestInfo HitTest(int x, int y)
{
HitTestInfo hti = new HitTestInfo();
if (!this.layout.Inside.Contains(x, y))
{
return hti;
}
if (this.horizScrollBar != null && this.horizScrollBar.Visible && this.horizScrollBar.Bounds.Contains(x, y))
{
hti.type = DataGridViewHitTestType.HorizontalScrollBar;
return hti;
}
if (this.vertScrollBar != null && this.vertScrollBar.Visible && this.vertScrollBar.Bounds.Contains(x, y))
{
hti.type = DataGridViewHitTestType.VerticalScrollBar;
return hti;
}
if (this.layout.TopLeftHeader.Contains(x, y))
{
hti.type = DataGridViewHitTestType.TopLeftHeader;
hti.typeInternal = DataGridViewHitTestTypeInternal.TopLeftHeader;
if (this.RightToLeftInternal)
{
hti.colStart = this.layout.TopLeftHeader.Right-1;
}
else
{
hti.colStart = this.layout.TopLeftHeader.Left;
}
hti.rowStart = this.layout.TopLeftHeader.Top;
if ((!this.RightToLeftInternal && this.layout.TopLeftHeader.Right - x < DATAGRIDVIEW_columnSizingHotZone) ||
(this.RightToLeftInternal && x - this.layout.TopLeftHeader.Left < DATAGRIDVIEW_columnSizingHotZone))
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Right;
if (this.RowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.TopLeftHeaderResizeLeft;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = this.layout.TopLeftHeader.Left - x - 1;
}
else
{
hti.mouseBarOffset = this.layout.TopLeftHeader.Right - x - 1;
}
}
}
else if (this.layout.TopLeftHeader.Top + this.layout.TopLeftHeader.Height - y < DATAGRIDVIEW_rowSizingHotZone)
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Bottom;
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.TopLeftHeaderResizeTop;
hti.mouseBarOffset = this.layout.TopLeftHeader.Top + this.layout.TopLeftHeader.Height - y - 1;
}
}
return hti;
}
// check for column resize / insertion
if (this.layout.ColumnHeaders.Contains(x, y))
{
int xColumnLeftEdge; // this is actually the right edge in RTL mode
hti.col = GetColumnIndexFromX(x, out xColumnLeftEdge);
if (hti.col < 0)
{
return HitTestInfo.Nowhere;
}
Debug.Assert(xColumnLeftEdge == GetColumnXFromIndex(hti.col));
hti.type = DataGridViewHitTestType.ColumnHeader;
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnHeader;
hti.rowStart = this.layout.ColumnHeaders.Top;
hti.colStart = xColumnLeftEdge;
int columnWidth = this.Columns[hti.col].Thickness;
if ((!this.RightToLeftInternal && xColumnLeftEdge + columnWidth - x < DATAGRIDVIEW_columnSizingHotZone) ||
(this.RightToLeftInternal && x - xColumnLeftEdge + columnWidth < DATAGRIDVIEW_columnSizingHotZone))
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Right;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = xColumnLeftEdge - columnWidth - x + 1;
}
else
{
hti.mouseBarOffset = xColumnLeftEdge + columnWidth - x - 1;
}
DataGridViewColumn dataGridViewColumn = this.Columns[hti.col];
if (dataGridViewColumn.Resizable == DataGridViewTriState.True &&
(dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.None || dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill))
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnResizeRight;
}
else
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnHeaderRight;
}
}
else if ((!this.RightToLeftInternal && x - xColumnLeftEdge < DATAGRIDVIEW_columnSizingHotZone) ||
(this.RightToLeftInternal && xColumnLeftEdge - x < DATAGRIDVIEW_columnSizingHotZone))
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Left;
DataGridViewColumn dataGridViewColumn = null;
// VS Whidbey bug 317105 - Condition unnecessary
//if (hti.col != this.displayedBandsInfo.FirstDisplayedScrollingCol || this.displayedBandsInfo.LastTotallyDisplayedScrollingCol >= 0)
//{
dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[hti.col],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
//}
if (dataGridViewColumn != null)
{
hti.adjacentCol = dataGridViewColumn.Index;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = xColumnLeftEdge - x + 1;
}
else
{
hti.mouseBarOffset = xColumnLeftEdge - x - 1;
}
if (dataGridViewColumn.Resizable == DataGridViewTriState.True &&
(dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.None || dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill))
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnResizeLeft;
}
else
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnHeaderLeft;
}
}
else
{
if (this.RowHeadersVisible && this.RowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.TopLeftHeaderResizeRight;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = xColumnLeftEdge - x;
}
else
{
hti.mouseBarOffset = xColumnLeftEdge - x - 1;
}
}
else
{
hti.typeInternal = DataGridViewHitTestTypeInternal.FirstColumnHeaderLeft;
}
}
}
else if (this.layout.ColumnHeaders.Bottom - y < DATAGRIDVIEW_rowSizingHotZone)
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Bottom;
if (/*!this.RowHeadersVisible &&*/ this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnHeadersResizeBottom;
hti.mouseBarOffset = this.layout.ColumnHeaders.Bottom - y - 1;
}
}
}
// check for row resize
if (this.layout.RowHeaders.Contains(x, y))
{
int yRowTopEdge;
hti.row = GetRowIndexFromY(y, out yRowTopEdge);
if (hti.row < 0)
{
return HitTestInfo.Nowhere;
}
Debug.Assert(yRowTopEdge == GetRowYFromIndex(hti.row));
hti.type = DataGridViewHitTestType.RowHeader;
hti.typeInternal = DataGridViewHitTestTypeInternal.RowHeader;
hti.rowStart = yRowTopEdge;
if (this.RightToLeftInternal)
{
hti.colStart = this.layout.RowHeaders.Right-1;
}
else
{
hti.colStart = this.layout.RowHeaders.Left;
}
int rowHeight = this.Rows.SharedRow(hti.row).GetHeight(hti.row);
if (yRowTopEdge + rowHeight - y < DATAGRIDVIEW_rowSizingHotZone)
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Bottom;
if (RowIsResizable(hti.row) && this.AutoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.RowResizeBottom;
hti.mouseBarOffset = yRowTopEdge + rowHeight - y - 1;
}
}
else if (y - yRowTopEdge < DATAGRIDVIEW_rowSizingHotZone)
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Top;
int indexTmp = -1;
if (hti.row != this.displayedBandsInfo.FirstDisplayedScrollingRow || this.displayedBandsInfo.NumDisplayedFrozenRows > 0)
{
indexTmp = this.Rows.GetPreviousRow(hti.row, DataGridViewElementStates.Visible);
}
if (indexTmp != -1)
{
if (RowIsResizable(indexTmp) && this.AutoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.RowResizeTop;
hti.adjacentRow = indexTmp;
hti.mouseBarOffset = yRowTopEdge - y - 1;
}
}
else
{
if (this.ColumnHeadersVisible && this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.TopLeftHeaderResizeBottom;
hti.mouseBarOffset = yRowTopEdge - y - 1;
}
}
}
else if ((!this.RightToLeftInternal && this.layout.RowHeaders.Right - x < DATAGRIDVIEW_columnSizingHotZone) ||
(this.RightToLeftInternal && x - this.layout.RowHeaders.Left < DATAGRIDVIEW_columnSizingHotZone))
{
//hti.edge = DataGridViewHitTestTypeCloseEdge.Right;
if (this.RowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.RowHeadersResizeRight;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = this.layout.RowHeaders.Left - x - 1;
}
else
{
hti.mouseBarOffset = this.layout.RowHeaders.Right - x - 1;
}
}
}
}
if (this.layout.Data.Contains(x, y))
{
int xColumnLeftEdge, yRowTopEdge;
hti.col = GetColumnIndexFromX(x, out xColumnLeftEdge);
hti.row = GetRowIndexFromY(y, out yRowTopEdge);
if (hti.col < 0 || hti.row < 0)
{
return HitTestInfo.Nowhere;
}
Debug.Assert(xColumnLeftEdge == GetColumnXFromIndex(hti.col));
Debug.Assert(yRowTopEdge == GetRowYFromIndex(hti.row));
hti.type = DataGridViewHitTestType.Cell;
hti.typeInternal = DataGridViewHitTestTypeInternal.Cell;
hti.rowStart = yRowTopEdge;
hti.colStart = xColumnLeftEdge;
if (!this.ColumnHeadersVisible)
{
int columnWidth = this.Columns[hti.col].Thickness;
if ((!this.RightToLeftInternal && xColumnLeftEdge + columnWidth - x < DATAGRIDVIEW_columnSizingHotZone) ||
(this.RightToLeftInternal && x - xColumnLeftEdge + columnWidth < DATAGRIDVIEW_columnSizingHotZone))
{
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = xColumnLeftEdge - columnWidth - x + 1;
}
else
{
hti.mouseBarOffset = xColumnLeftEdge + columnWidth - x - 1;
}
DataGridViewColumn dataGridViewColumn = this.Columns[hti.col];
if (dataGridViewColumn.Resizable == DataGridViewTriState.True &&
(dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.None || dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill))
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnResizeRight;
}
return hti;
}
else if ((!this.RightToLeftInternal && x - xColumnLeftEdge < DATAGRIDVIEW_columnSizingHotZone) ||
(this.RightToLeftInternal && xColumnLeftEdge - x < DATAGRIDVIEW_columnSizingHotZone))
{
DataGridViewColumn dataGridViewColumn = null;
if (hti.col != this.displayedBandsInfo.FirstDisplayedScrollingCol || this.displayedBandsInfo.LastTotallyDisplayedScrollingCol >= 0)
{
dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[hti.col],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
}
if (dataGridViewColumn != null)
{
hti.adjacentCol = dataGridViewColumn.Index;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = xColumnLeftEdge - x + 1;
}
else
{
hti.mouseBarOffset = xColumnLeftEdge - x - 1;
}
if (dataGridViewColumn.Resizable == DataGridViewTriState.True &&
(dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.None || dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill))
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnResizeLeft;
}
return hti;
}
else
{
if (this.RowHeadersVisible && this.RowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.RowHeadersResizeLeft;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = xColumnLeftEdge - x;
}
else
{
hti.mouseBarOffset = xColumnLeftEdge - x - 1;
}
return hti;
}
}
}
}
else if ((!this.RightToLeftInternal && x - xColumnLeftEdge < DATAGRIDVIEW_columnSizingHotZone) ||
(this.RightToLeftInternal && xColumnLeftEdge - x < DATAGRIDVIEW_columnSizingHotZone))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
Debug.Assert(dataGridViewColumn != null);
if (hti.col == dataGridViewColumn.Index &&
this.RowHeadersVisible &&
this.RowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.RowHeadersResizeLeft;
if (this.RightToLeftInternal)
{
hti.mouseBarOffset = xColumnLeftEdge - x;
}
else
{
hti.mouseBarOffset = xColumnLeftEdge - x - 1;
}
return hti;
}
}
if (!this.RowHeadersVisible)
{
int rowHeight = this.Rows.SharedRow(hti.row).GetHeight(hti.row);
if (yRowTopEdge + rowHeight - y < DATAGRIDVIEW_rowSizingHotZone)
{
if (RowIsResizable(hti.row) && this.AutoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.RowResizeBottom;
hti.mouseBarOffset = yRowTopEdge + rowHeight - y - 1;
}
}
else if (y - yRowTopEdge < DATAGRIDVIEW_rowSizingHotZone)
{
int indexTmp = -1;
if (hti.row != this.displayedBandsInfo.FirstDisplayedScrollingRow || this.displayedBandsInfo.NumDisplayedFrozenRows > 0)
{
indexTmp = this.Rows.GetPreviousRow(hti.row,
DataGridViewElementStates.Visible);
}
if (indexTmp != -1)
{
if (RowIsResizable(indexTmp) && this.AutoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.RowResizeTop;
hti.adjacentRow = indexTmp;
hti.mouseBarOffset = yRowTopEdge - y - 1;
}
}
else
{
if (this.ColumnHeadersVisible && this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnHeadersResizeTop;
hti.mouseBarOffset = yRowTopEdge - y - 1;
}
}
}
}
else if (y - yRowTopEdge < DATAGRIDVIEW_rowSizingHotZone)
{
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
Debug.Assert(rowIndex >= 0);
if (hti.row == rowIndex &&
this.ColumnHeadersVisible &&
this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.EnableResizing)
{
hti.typeInternal = DataGridViewHitTestTypeInternal.ColumnHeadersResizeTop;
hti.mouseBarOffset = yRowTopEdge - y - 1;
}
}
}
return hti;
}
private void HorizScrollTimer_Tick(object sender, System.EventArgs e)
{
BeginInvoke(new MethodInvoker(HorizScrollTimerHandler));
}
private void HorizScrollTimerHandler()
{
Debug.Assert(this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] || this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect]);
Point ptMouse = PointToClient(Control.MousePosition);
HitTestInfo hti = HitTest(ptMouse.X, ptMouse.Y);
int xOffset, yOffset, mouseX = ptMouse.X, mouseY = ptMouse.Y;
if (GetOutOfBoundCorrectedHitTestInfo(ref hti, ref mouseX, ref mouseY, out xOffset, out yOffset))
{
if (xOffset != 0)
{
int absXOffset = Math.Abs(xOffset), normOffset = xOffset / absXOffset;
ScrollColumns(normOffset);
this.horizScrollTimer.Interval = GetColumnScrollRate(absXOffset);
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect])
{
hti = HitTest(ptMouse.X+(this.RightToLeftInternal?1:-1)*(xOffset+normOffset), mouseY);
if (hti.col >= 0)
{
OnColumnSelectMouseMove(hti);
}
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect])
{
if (yOffset != 0)
{
hti = HitTest(ptMouse.X+(this.RightToLeftInternal?1:-1)*(xOffset+normOffset), ptMouse.Y-yOffset-(yOffset/Math.Abs(yOffset)));
}
else
{
hti = HitTest(ptMouse.X+(this.RightToLeftInternal?1:-1)*(xOffset+normOffset), mouseY);
}
if (hti.col >= 0 && hti.row >= 0)
{
OnCellSelectMouseMove(hti);
}
}
}
else
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] && hti.col >= 0)
{
OnColumnSelectMouseMove(hti);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect] && hti.col >= 0 && hti.row >= 0)
{
OnCellSelectMouseMove(hti);
}
this.HorizScrollTimer.Enabled = false;
}
}
}
// Returns true for success, returns false when the OnDataError event cancels the operation.
private bool InitializeEditingCellValue(ref DataGridViewCellStyle dataGridViewCellStyle, ref DataGridViewCell dataGridViewCell)
{
DataGridViewDataErrorEventArgs dgvdee = null;
// Save unedited value so we can restore it later if parsing of new value fails
this.uneditedFormattedValue = dataGridViewCell.GetFormattedValue(this.ptCurrentCell.Y, ref dataGridViewCellStyle, DataGridViewDataErrorContexts.Formatting);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges] = true;
try
{
IDataGridViewEditingCell dataGridViewEditingCell = dataGridViewCell as IDataGridViewEditingCell;
Debug.Assert(dataGridViewEditingCell != null);
object currentFormattedValue = dataGridViewEditingCell.GetEditingCellFormattedValue(DataGridViewDataErrorContexts.Formatting);
if ((currentFormattedValue == null && this.uneditedFormattedValue != null) ||
(currentFormattedValue != null && this.uneditedFormattedValue == null) ||
(currentFormattedValue != null && !this.uneditedFormattedValue.Equals(currentFormattedValue)))
{
Debug.Assert(this.ptCurrentCell.X == dataGridViewCell.ColumnIndex);
dataGridViewCell = this.Rows[this.ptCurrentCell.Y].Cells[this.ptCurrentCell.X]; // unshare the edited cell
dataGridViewEditingCell = dataGridViewCell as IDataGridViewEditingCell;
dataGridViewEditingCell.EditingCellFormattedValue = this.uneditedFormattedValue;
dataGridViewEditingCell.EditingCellValueChanged = false;
}
}
catch (Exception exception)
{
if (ClientUtils.IsCriticalException(exception))
{
throw;
}
dgvdee = new DataGridViewDataErrorEventArgs(exception, this.ptCurrentCell.X,
this.ptCurrentCell.Y,
DataGridViewDataErrorContexts.InitialValueRestoration);
OnDataErrorInternal(dgvdee);
}
finally
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges] = false;
}
if (dgvdee != null)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
return !dgvdee.Cancel;
}
return true;
}
// Returns true for success, returns false when the OnDataError event cancels the operation.
private bool InitializeEditingControlValue(ref DataGridViewCellStyle dataGridViewCellStyle, DataGridViewCell dataGridViewCell)
{
Debug.Assert(dataGridViewCell != null);
Debug.Assert(this.editingControl != null);
DataGridViewDataErrorEventArgs dgvdee = null;
object initialFormattedValue = dataGridViewCell.GetFormattedValue(this.ptCurrentCell.Y, ref dataGridViewCellStyle, DataGridViewDataErrorContexts.Formatting);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlChanging] = true;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges] = true;
try
{
dataGridViewCell.InitializeEditingControl(this.ptCurrentCell.Y, initialFormattedValue, dataGridViewCellStyle);
((IDataGridViewEditingControl)this.editingControl).EditingControlValueChanged = false;
}
catch (Exception exception)
{
if (ClientUtils.IsCriticalException(exception))
{
throw;
}
dgvdee = new DataGridViewDataErrorEventArgs(exception, this.ptCurrentCell.X,
this.ptCurrentCell.Y,
DataGridViewDataErrorContexts.InitialValueRestoration);
OnDataErrorInternal(dgvdee);
}
finally
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlChanging] = false;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges] = false;
}
if (dgvdee != null)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
return !dgvdee.Cancel;
}
// Save unedited value so we can restore it later if parsing of new value fails
this.uneditedFormattedValue = initialFormattedValue;
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.InvalidateCell"]/*' />
public void InvalidateCell(DataGridViewCell dataGridViewCell)
{
if (dataGridViewCell == null)
{
throw new ArgumentNullException("dataGridViewCell");
}
if (dataGridViewCell.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_CellDoesNotBelongToDataGridView));
}
InvalidateCellPrivate(dataGridViewCell);
}
private void InvalidateCellPrivate(DataGridViewCell dataGridViewCell)
{
Debug.Assert(dataGridViewCell != null);
Debug.Assert(dataGridViewCell.DataGridView == this);
InvalidateCell(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.InvalidateCell1"]/*' />
public void InvalidateCell(int columnIndex, int rowIndex)
{
if (columnIndex < -1 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex < -1 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
InvalidateCellPrivate(columnIndex, rowIndex);
}
private void InvalidateCellPrivate(int columnIndex, int rowIndex)
{
if (this.IsHandleCreated)
{
Rectangle cellDisplayRect = GetCellAdjustedDisplayRectangle(columnIndex, rowIndex, true);
if (!cellDisplayRect.IsEmpty)
{
Invalidate(cellDisplayRect);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.InvalidateColumn"]/*' />
/// <devdoc>
/// Invalidate the painting region for the column specified.
/// </devdoc>
public void InvalidateColumn(int columnIndex)
{
if (columnIndex < 0 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
InvalidateColumnInternal(columnIndex);
}
internal void InvalidateColumnInternal(int columnIndex)
{
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count);
if (this.IsHandleCreated)
{
Rectangle columnDisplayRect = GetColumnDisplayRectanglePrivate(columnIndex, true);
if (!columnDisplayRect.IsEmpty)
{
Invalidate(columnDisplayRect);
}
}
}
private void InvalidateData()
{
if (this.IsHandleCreated)
{
Invalidate(this.layout.Data);
}
}
/// <devdoc>
/// Invalidates the scrollable area of the DataGridView.
/// </devdoc>
private void InvalidateInside()
{
if (this.IsHandleCreated)
{
Invalidate(this.layout.Inside);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.InvalidateRow"]/*' />
/// <devdoc>
/// Invalidate the painting region for the row specified.
/// </devdoc>
public void InvalidateRow(int rowIndex)
{
if (rowIndex < 0 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
InvalidateRowPrivate(rowIndex);
}
private void InvalidateRowPrivate(int rowIndex)
{
Debug.Assert(rowIndex >= 0 && rowIndex < this.Rows.Count);
if (this.IsHandleCreated)
{
Rectangle rowDisplayRect = GetRowDisplayRectanglePrivate(rowIndex, true);
if (!rowDisplayRect.IsEmpty)
{
Invalidate(rowDisplayRect);
}
}
}
private void InvalidateRowHeights()
{
this.Rows.InvalidateCachedRowsHeights();
if (this.IsHandleCreated)
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
Invalidate();
}
}
private void InvalidateRows(int lo, int hi)
{
Debug.Assert(lo <= hi);
Debug.Assert(lo < this.Rows.Count);
Debug.Assert(hi < this.Rows.Count);
if (this.Rows.GetRowCount(DataGridViewElementStates.Visible) == 0)
{
return;
}
Rectangle rowDisplayRect, data;
int top, bottom;
data = this.layout.Data;
// If "lo" is not visible, then get the next visible row
if ((this.Rows.GetRowState(lo) & DataGridViewElementStates.Visible) == 0)
{
lo = this.Rows.GetNextRow(lo, DataGridViewElementStates.Visible);
}
if (lo == -1)
{
// there are no visible rows below "lo" so there is nothing to invalidate.
return;
}
// If "hi" is not visible, then get the previous visible row
if ((this.Rows.GetRowState(hi) & DataGridViewElementStates.Visible) == 0)
{
hi = this.Rows.GetPreviousRow(hi, DataGridViewElementStates.Visible);
}
Debug.Assert(lo <= hi);
Debug.Assert(lo > -1);
rowDisplayRect = this.GetRowDisplayRectangle(lo, true /*cutOverflow*/);
if (rowDisplayRect.IsEmpty)
{
// The top row is offscreen
if ((this.Rows.GetRowState(lo) & DataGridViewElementStates.Frozen) != 0)
{
// "lo" is a frozen row which is offscreen.
// This means that "lo" and any other row below it are offscreen.
return;
}
else if (this.displayedBandsInfo.NumDisplayedScrollingRows == 0)
{
// "lo" and all the rows below are scrolling rows but no scrolling rows are displayed.
return;
}
else if (lo >= this.displayedBandsInfo.FirstDisplayedScrollingRow &&
this.Rows.GetRowCount(DataGridViewElementStates.Visible,
this.displayedBandsInfo.FirstDisplayedScrollingRow,
lo) >= this.displayedBandsInfo.NumDisplayedScrollingRows)
{
// "lo" is a scrolling row whose coordinates are below the last visible row.
return;
}
else
{
// "lo" is a scrolling row "behind" frozen rows.
// Start invalidating at the top of the first displayed scrolling row.
top = this.GetRowDisplayRectangle(this.displayedBandsInfo.FirstDisplayedScrollingRow, true /*cutOverflow*/).Top;
}
}
else
{
top = rowDisplayRect.Top;
}
rowDisplayRect = this.GetRowDisplayRectangle(hi, true /*cutOverflow*/);
if (rowDisplayRect.IsEmpty)
{
// The bottom row is offscreen.
if ((this.Rows.GetRowState(hi) & DataGridViewElementStates.Frozen) == DataGridViewElementStates.Frozen)
{
// "hi" is a frozen row offscreen and "lo" is a frozen row on screen.
// Invalidate all the way to the bottom
bottom = data.Bottom;
}
else if (hi > this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
// "hi" is a scrolling row offscreen which is beyond the firstDisplayedScrollingRow
// Invalidate all the way to the bottom again.
bottom = data.Bottom;
}
else if (this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen) == 0)
{
// "hi" is a scrolling row above the first displayed scrolling row and there are no frozen rows.
// There is nothing to invalidate.
return;
}
else
{
// "hi" is a scrolling row which is "behind" the frozen rows.
// Invalidate all the way to the bottom of the frozen rows
// Compute the bottom of the last displayed frozen row.
// There may be invisible rows between the frozen rows.
bottom = 0;
for (int i = 0; i < this.displayedBandsInfo.NumDisplayedFrozenRows;)
{
if ((this.Rows.GetRowState(i) & DataGridViewElementStates.Visible) == 0)
{
continue;
}
if (i == this.displayedBandsInfo.NumDisplayedFrozenRows - 1)
{
bottom = this.GetRowDisplayRectangle(i, true /*cutOverflow*/).Bottom;
break;
}
i ++;
}
if (bottom <= top)
{
// In this case both "lo" and "hi" are two scrolling rows behind the frozen rows.
// Nothing to invalidate.
return;
}
}
}
else
{
bottom = rowDisplayRect.Bottom;
}
Invalidate(new Rectangle(data.X, top, data.Width, bottom - top));
}
private void InvalidateScrollBars()
{
// invalidate the horizontal and the vertical scrollbars
// note that the scrollbars can be null - this happens when
// the control has been disposed.
if (this.horizScrollBar != null && this.horizScrollBar.Visible)
{
this.horizScrollBar.Invalidate();
}
if (this.vertScrollBar != null && this.vertScrollBar.Visible)
{
this.vertScrollBar.Invalidate();
}
}
private bool IsColumnOutOfBounds(int columnIndex)
{
return columnIndex >= this.Columns.Count || columnIndex == -1;
}
private bool IsInnerCellOutOfBounds(int columnIndex, int rowIndex)
{
return columnIndex >= this.Columns.Count || rowIndex >= this.Rows.Count || columnIndex == -1 || rowIndex == -1;
}
private bool IsRowOutOfBounds(int rowIndex)
{
return rowIndex >= this.Rows.Count || rowIndex == -1;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.IsInputChar"]/*' />
protected override bool IsInputChar(char charCode)
{
if (this.editingControl != null &&
this.dataGridViewState1[DATAGRIDVIEWSTATE1_forwardCharMessage])
{
// Do not process key press in ProcessDialogChar.
return true;
}
else
{
return base.IsInputChar(charCode);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.IsInputKey"]/*' />
protected override bool IsInputKey(Keys keyData)
{
if ((keyData & Keys.Alt) == Keys.Alt)
{
return false;
}
switch (keyData & Keys.KeyCode)
{
case Keys.Escape:
{
return this.IsEscapeKeyEffective;
}
case Keys.Tab:
{
return GetTabKeyEffective((keyData & Keys.Shift) == Keys.Shift, (keyData & Keys.Control) == Keys.Control);
}
case Keys.A:
{
if ((keyData & (Keys.Control | Keys.Shift | Keys.Alt)) == Keys.Control)
{
return true;
}
break;
}
case Keys.C:
case Keys.Insert:
{
if ((keyData & (Keys.Control | Keys.Shift | Keys.Alt)) == Keys.Control)
{
return true;
}
break;
}
case Keys.Space:
{
if ((keyData & (Keys.Control | Keys.Shift | Keys.Alt)) == Keys.Shift &&
(this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect ||
this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect) &&
this.ptCurrentCell.X != -1)
{
return true;
}
break;
}
case Keys.Up:
case Keys.Down:
case Keys.Left:
case Keys.Right:
case Keys.Home:
case Keys.End:
case Keys.Next:
case Keys.Prior:
case Keys.Enter:
case Keys.Delete:
case Keys.D0:
case Keys.NumPad0:
case Keys.F2:
case Keys.F3:
{
return true;
}
}
return base.IsInputKey(keyData);
}
/// <devdoc>
/// Determines if Scrollbars should be visible,
/// updates their bounds and the bounds of all
/// other regions in the dataGridView's Layout.
/// </devdoc>
private void LayoutScrollBars()
{
SuspendLayout();
try
{
// Scrollbars are a tricky issue.
// We need to see if we can cram our columns and rows
// in without scrollbars and if they don't fit, we make
// scrollbars visible and then fixup our regions for the
// data.
bool allowHorizScrollbar = ((this.scrollBars == ScrollBars.Both) || (this.scrollBars == ScrollBars.Horizontal)) &&
this.dataGridViewState2[DATAGRIDVIEWSTATE2_allowHorizontalScrollbar];
bool allowVertScrollbar = (this.scrollBars == ScrollBars.Both) || (this.scrollBars == ScrollBars.Vertical);
bool needHorizScrollbarWithoutVertScrollbar = false;
bool needHorizScrollbar = false;
bool needVertScrollbar = false;
bool rightToLeftInternal = this.RightToLeftInternal;
int oldfirstDisplayedScrollingRow;
int totalVisibleColCount = this.Columns.GetColumnCount(DataGridViewElementStates.Visible);
int totalVisibleRowCount = this.Rows.GetRowCount(DataGridViewElementStates.Visible);
int totalVisibleWidth = this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible);
int totalVisibleFrozenWidth = this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
// Expensive call - dataGridView could have a mode where no row is resizable which would result in better perfs
int totalVisibleHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible);
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
int horizScrollBarHeight = this.horizScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
int vertScrollBarWidth = this.vertScrollBar.Width = SystemInformation.VerticalScrollBarWidth;
if (allowHorizScrollbar &&
totalVisibleWidth > this.layout.Data.Width && totalVisibleFrozenWidth < this.layout.Data.Width &&
horizScrollBarHeight <= this.layout.Data.Height)
{
int oldDataHeight = this.layout.Data.Height;
this.layout.Data.Height -= horizScrollBarHeight;
Debug.Assert(this.layout.Data.Height >= 0);
needHorizScrollbarWithoutVertScrollbar = needHorizScrollbar = true;
if (totalVisibleWidth - this.layout.Data.Width <= vertScrollBarWidth ||
this.layout.Data.Width - totalVisibleFrozenWidth <= vertScrollBarWidth)
{
// Would we still need a horizontal scrollbar if there were a vertical one?
oldfirstDisplayedScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
ComputeVisibleRows();
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)))
{
needHorizScrollbar = (totalVisibleFrozenWidth < this.layout.Data.Width - vertScrollBarWidth);
}
this.displayedBandsInfo.FirstDisplayedScrollingRow = oldfirstDisplayedScrollingRow;
}
if (needHorizScrollbar)
{
if (this.layout.RowHeadersVisible)
{
this.layout.RowHeaders.Height -= horizScrollBarHeight;
Debug.Assert(this.layout.RowHeaders.Height >= 0);
}
}
else
{
// Restore old data height because turns out a horizontal scroll bar wouldn't make sense
this.layout.Data.Height = oldDataHeight;
}
}
oldfirstDisplayedScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
ComputeVisibleRows();
if (allowVertScrollbar &&
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 &&
vertScrollBarWidth <= this.layout.Data.Width)
{
this.layout.Data.Width -= vertScrollBarWidth;
Debug.Assert(this.layout.Data.Width >= 0);
if (rightToLeftInternal)
{
this.layout.Data.X += vertScrollBarWidth;
}
if (this.layout.ColumnHeadersVisible)
{
this.layout.ColumnHeaders.Width -= vertScrollBarWidth;
Debug.Assert(this.layout.ColumnHeaders.Width >= 0);
if (rightToLeftInternal)
{
this.layout.ColumnHeaders.X += vertScrollBarWidth;
}
}
needVertScrollbar = true;
}
this.displayedBandsInfo.FirstDisplayedScrollingCol = ComputeFirstVisibleScrollingColumn();
// we compute the number of visible columns only after we set up the vertical scroll bar.
ComputeVisibleColumns();
if (allowHorizScrollbar &&
needVertScrollbar && !needHorizScrollbar &&
totalVisibleWidth > this.layout.Data.Width && totalVisibleFrozenWidth < this.layout.Data.Width &&
horizScrollBarHeight <= this.layout.Data.Height)
{
this.displayedBandsInfo.FirstDisplayedScrollingRow = oldfirstDisplayedScrollingRow;
if (this.layout.ColumnHeadersVisible)
{
this.layout.ColumnHeaders.Width += vertScrollBarWidth;
if (rightToLeftInternal)
{
this.layout.ColumnHeaders.X -= vertScrollBarWidth;
}
}
this.layout.Data.Width += vertScrollBarWidth;
if (rightToLeftInternal)
{
this.layout.Data.X -= vertScrollBarWidth;
}
this.layout.Data.Height -= horizScrollBarHeight;
Debug.Assert(this.layout.Data.Height >= 0);
needVertScrollbar = false;
ComputeVisibleRows();
if (this.displayedBandsInfo.NumTotallyDisplayedFrozenRows == this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen) &&
this.displayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount &&
(totalVisibleHeight - totalVisibleFrozenHeight != ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight)) &&
this.layout.Data.Height > totalVisibleFrozenHeight &&
vertScrollBarWidth <= this.layout.Data.Width)
{
this.layout.Data.Width -= vertScrollBarWidth;
Debug.Assert(this.layout.Data.Width >= 0);
if (rightToLeftInternal)
{
this.layout.Data.X += vertScrollBarWidth;
}
if (this.layout.ColumnHeadersVisible)
{
this.layout.ColumnHeaders.Width -= vertScrollBarWidth;
Debug.Assert(this.layout.ColumnHeaders.Width >= 0);
if (rightToLeftInternal)
{
this.layout.ColumnHeaders.X += vertScrollBarWidth;
}
}
needVertScrollbar = true;
}
if (needVertScrollbar)
{
needHorizScrollbar = true;
}
else
{
needHorizScrollbar = needHorizScrollbarWithoutVertScrollbar;
}
}
this.layout.ResizeBoxRect = new Rectangle();
if (needVertScrollbar && needHorizScrollbar)
{
this.layout.ResizeBoxRect = new Rectangle(
rightToLeftInternal ? this.layout.Data.X - this.vertScrollBar.Width : this.layout.Data.Right,
this.layout.Data.Bottom,
this.vertScrollBar.Width,
this.horizScrollBar.Height);
}
if (needHorizScrollbar && totalVisibleColCount > 0)
{
int widthNotVisible = totalVisibleWidth - this.layout.Data.Width;
this.horizScrollBar.Minimum = 0;
this.horizScrollBar.Maximum = totalVisibleWidth - totalVisibleFrozenWidth;
Debug.Assert(this.horizScrollBar.Maximum > 0);
this.horizScrollBar.SmallChange = 1;
this.horizScrollBar.LargeChange = Math.Max(totalVisibleWidth - totalVisibleFrozenWidth - widthNotVisible, 0);
this.horizScrollBar.Enabled = this.Enabled;
this.horizScrollBar.Bounds = new Rectangle(
rightToLeftInternal ? this.layout.Inside.X + this.layout.ResizeBoxRect.Width : this.layout.Inside.X,
this.layout.Data.Bottom,
this.layout.Inside.Width - this.layout.ResizeBoxRect.Width,
this.horizScrollBar.Height);
this.horizScrollBar.Visible = true;
this.horizScrollBar.Invalidate();
}
else
{
this.horizScrollBar.Visible = false;
this.HorizontalOffset = 0;
this.horizScrollBar.Enabled = false;
this.horizScrollBar.Minimum = 0;
this.horizScrollBar.Maximum = 1;
this.horizScrollBar.SmallChange = 1;
this.horizScrollBar.LargeChange = 1;
this.horizScrollBar.Value = 0;
}
if (needVertScrollbar)
{
int vertScrollBarTop = this.layout.Data.Y;
int vertScrollBarHeight = this.layout.Data.Height;
if (this.layout.ColumnHeadersVisible)
{
vertScrollBarTop = this.layout.ColumnHeaders.Y;
vertScrollBarHeight += this.layout.ColumnHeaders.Height;
}
else if (this.SingleHorizontalBorderAdded)
{
vertScrollBarTop--;
vertScrollBarHeight++;
}
this.vertScrollBar.Minimum = 0;
this.vertScrollBar.Maximum = totalVisibleHeight - totalVisibleFrozenHeight;
Debug.Assert(this.vertScrollBar.Maximum > 0);
this.vertScrollBar.Value = ComputeHeightOfScrolledOffRows();
this.vertScrollBar.LargeChange = this.layout.Data.Height - totalVisibleFrozenHeight;
this.vertScrollBar.Bounds = new Rectangle(
rightToLeftInternal ? this.layout.Data.X - this.vertScrollBar.Width : this.layout.Data.Right,
vertScrollBarTop,
this.vertScrollBar.Width,
vertScrollBarHeight);
this.vertScrollBar.Enabled = this.Enabled;
this.vertScrollBar.Visible = true;
this.vertScrollBar.Invalidate();
this.verticalOffset = this.vertScrollBar.Value;
}
else
{
this.vertScrollBar.Visible = false;
this.verticalOffset = ComputeHeightOfScrolledOffRows();
this.vertScrollBar.Enabled = false;
this.vertScrollBar.Minimum = 0;
this.vertScrollBar.Maximum = 1;
this.vertScrollBar.LargeChange = 1;
this.vertScrollBar.Value = 0;
}
}
finally
{
ResumeLayout(false);
}
}
private void MakeFirstDisplayedCellCurrentCell(bool includeNewRow)
{
// No current cell - try to set the first displayed cell to be the current one.
Point firstDisplayedCellAddress = this.FirstDisplayedCellAddress;
if (firstDisplayedCellAddress.X != -1 &&
(includeNewRow ||
!this.AllowUserToAddRowsInternal ||
firstDisplayedCellAddress.Y != this.Rows.Count - 1))
{
bool success = SetAndSelectCurrentCellAddress(firstDisplayedCellAddress.X,
firstDisplayedCellAddress.Y,
true /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/,
true /*clearSelection*/,
false /*forceCurrentCellSelection (unused)*/);
Debug.Assert(success);
}
}
private static DataGridViewAutoSizeRowMode MapAutoSizeRowsModeToRowMode(DataGridViewAutoSizeRowsMode autoSizeRowsMode)
{
switch (autoSizeRowsMode)
{
case DataGridViewAutoSizeRowsMode.AllHeaders:
return DataGridViewAutoSizeRowMode.RowHeader;
case DataGridViewAutoSizeRowsMode.DisplayedHeaders:
return DataGridViewAutoSizeRowMode.RowHeader;
case DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders:
return DataGridViewAutoSizeRowMode.AllCellsExceptHeader;
case DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders:
return DataGridViewAutoSizeRowMode.AllCellsExceptHeader;
case DataGridViewAutoSizeRowsMode.AllCells:
return DataGridViewAutoSizeRowMode.AllCells;
case DataGridViewAutoSizeRowsMode.DisplayedCells:
return DataGridViewAutoSizeRowMode.AllCells;
default:
Debug.Fail("Unexpected autoSizeRowsMode value in MapAutoSizeRowsModeToRowMode");
return DataGridViewAutoSizeRowMode.RowHeader;
}
}
private void MoveColumnHeadersOrRowResize(MouseEventArgs e)
{
this.lastRowSplitBar = this.currentRowSplitBar;
this.currentRowSplitBar = e.Y;
Rectangle lastSplitBarRect = CalcRowResizeFeedbackRect(this.lastRowSplitBar);
if (this.editingControl != null &&
!this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlHidden] &&
this.editingPanel.Bounds.IntersectsWith(lastSplitBarRect))
{
this.editingPanel.Invalidate();
this.editingPanel.Update();
this.editingControl.Invalidate();
this.editingControl.Update();
}
Invalidate(lastSplitBarRect);
Invalidate(CalcRowResizeFeedbackRect(this.currentRowSplitBar));
}
private void MapDataGridViewColumnToDataBoundField(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(this.DataSource != null, "this method should only be called when we have a data connection");
Debug.Assert(dataGridViewColumn.DataPropertyName.Length != 0, "this method should be called only for columns which have DataPropertyName set");
DataGridViewDataConnection conn = this.DataConnection;
int boundColumnIndex = ((conn == null) ? -1 : conn.BoundColumnIndex(dataGridViewColumn.DataPropertyName));
if (boundColumnIndex != -1)
{
dataGridViewColumn.IsDataBoundInternal = true;
dataGridViewColumn.BoundColumnIndex = boundColumnIndex;
dataGridViewColumn.BoundColumnConverter = conn.BoundColumnConverter(boundColumnIndex);
dataGridViewColumn.ValueType = conn.BoundColumnValueType(boundColumnIndex);
dataGridViewColumn.ReadOnly = conn.DataFieldIsReadOnly(dataGridViewColumn.BoundColumnIndex) || dataGridViewColumn.ReadOnly;
InvalidateColumnInternal(dataGridViewColumn.Index);
// Set the Sorting information on the data grid view according to the new DataPropertyName.
// RefreshColumns() has its own routine for setting the Sorting information so don't do this step
// if we are in RefreshColumns();
if (dataGridViewColumn.SortMode != DataGridViewColumnSortMode.NotSortable &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inRefreshColumns])
{
dataGridViewColumn.HeaderCell.SortGlyphDirection = conn.BoundColumnSortOrder(boundColumnIndex);
if (this.sortedColumn == null && dataGridViewColumn.HeaderCell.SortGlyphDirection != SortOrder.None)
{
this.sortedColumn = dataGridViewColumn;
this.sortOrder = dataGridViewColumn.HeaderCell.SortGlyphDirection;
// no need to sort because the back end is already sorted....
}
}
}
else
{
dataGridViewColumn.IsDataBoundInternal = false;
dataGridViewColumn.BoundColumnIndex = -1;
dataGridViewColumn.BoundColumnConverter = null;
InvalidateColumnInternal(dataGridViewColumn.Index);
}
}
private void MoveColumnRelocation(MouseEventArgs e, HitTestInfo hti)
{
this.lastHeaderShadow = e.X;
this.dataGridViewState2[DATAGRIDVIEWSTATE2_showColumnRelocationInsertion] = ColumnRelocationTarget(e, hti, out this.trackColumnEdge);
Invalidate(Rectangle.Union(this.layout.TopLeftHeader, this.layout.ColumnHeaders));
}
private void MoveRowHeadersOrColumnResize(int x)
{
this.lastColSplitBar = this.currentColSplitBar;
this.currentColSplitBar = x;
Rectangle lastSplitBarRect = CalcColResizeFeedbackRect(this.lastColSplitBar);
if (this.editingControl != null &&
!this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlHidden] &&
this.editingPanel.Bounds.IntersectsWith(lastSplitBarRect))
{
this.editingPanel.Invalidate();
this.editingPanel.Update();
this.editingControl.Invalidate();
this.editingControl.Update();
}
Invalidate(lastSplitBarRect);
Invalidate(CalcColResizeFeedbackRect(this.currentColSplitBar));
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.NotifyCurrentCellDirty"]/*' />
public virtual void NotifyCurrentCellDirty(bool dirty)
{
Debug.Assert(this.ptCurrentCell.X >= 0 && this.ptCurrentCell.X < this.Columns.Count);
Debug.Assert(this.ptCurrentCell.Y >= 0 && this.ptCurrentCell.Y < this.Rows.Count);
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_ignoringEditingChanges] == false)
{
// autosizing has no effect since edited value hasn't been committed
// and autosizing code only looks at committed values.
this.IsCurrentCellDirtyInternal = dirty;
if (dirty && this.editingControl != null && ((IDataGridViewEditingControl) this.editingControl).RepositionEditingControlOnValueChange)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
}
internal void OnAddedColumn(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn.Index >= 0);
Debug.Assert(dataGridViewColumn.Index < this.Columns.Count);
Debug.Assert(dataGridViewColumn.DataGridView == this);
if (dataGridViewColumn.DisplayIndex == -1 || dataGridViewColumn.DisplayIndex >= this.Columns.Count)
{
// Developer did not assign a DisplayIndex or picked a large number.
// Choose the Index as the DisplayIndex.
dataGridViewColumn.DisplayIndexInternal = dataGridViewColumn.Index;
this.Columns.InvalidateCachedColumnsOrder();
}
CorrectColumnDisplayIndexesAfterInsertion(dataGridViewColumn);
if (dataGridViewColumn.HasHeaderCell)
{
dataGridViewColumn.HeaderCell.DataGridViewInternal = this;
}
AdjustExpandingRows(dataGridViewColumn.Index, false /*fixedWidth*/);
DataGridViewAutoSizeColumnMode autoSizeColumnMode = dataGridViewColumn.InheritedAutoSizeMode;
Debug.Assert(autoSizeColumnMode != DataGridViewAutoSizeColumnMode.NotSet);
bool fixedColumnWidth = autoSizeColumnMode == DataGridViewAutoSizeColumnMode.None ||
autoSizeColumnMode == DataGridViewAutoSizeColumnMode.Fill;
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(dataGridViewColumn.Index, true /*fixedRowHeadersWidth*/, fixedColumnWidth);
}
if (!fixedColumnWidth)
{
// This is the first time the column autosizes. Save current column width for later reuse.
dataGridViewColumn.CachedThickness = dataGridViewColumn.Thickness;
AutoResizeColumnInternal(dataGridViewColumn.Index, (DataGridViewAutoSizeColumnCriteriaInternal)autoSizeColumnMode, true /*fixedHeight*/);
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
// Second round of column headers autosizing
AutoResizeColumnHeadersHeight(dataGridViewColumn.Index, true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
}
// Raise the ColumnAdded event
OnColumnAdded(new DataGridViewColumnEventArgs(dataGridViewColumn));
}
internal void OnAddedRow_PreNotification(int rowIndex)
{
Debug.Assert(rowIndex >= 0);
if (this.AllowUserToAddRowsInternal && this.newRowIndex == -1)
{
// The added row is necessarily the 'new row'
// Set the this.newRowIndex variable as early as possible.
Debug.Assert(rowIndex == this.Rows.Count - 1);
this.newRowIndex = rowIndex;
}
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
#if DEBUG
DataGridViewRow dataGridViewRowDebug = this.Rows.SharedRow(rowIndex);
foreach (DataGridViewCell dataGridViewCell in dataGridViewRowDebug.Cells)
{
Debug.Assert(!dataGridViewCell.Selected);
Debug.Assert(dataGridViewRowDebug.Index != -1 || !dataGridViewCell.HasValue);
}
#endif
// Update this.individualReadOnlyCells
if ((rowState & DataGridViewElementStates.ReadOnly) == 0 &&
!this.ReadOnly)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
foreach (DataGridViewCell dataGridViewCell in dataGridViewRow.Cells)
{
if (!dataGridViewCell.OwningColumn.ReadOnly && IsSharedCellReadOnly(dataGridViewCell, rowIndex))
{
this.individualReadOnlyCells.Add(dataGridViewCell);
}
}
}
}
internal void OnAddedRow_PostNotification(int rowIndex)
{
Debug.Assert(rowIndex >= 0);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if ((rowState & DataGridViewElementStates.Visible) != 0)
{
bool rowDisplayed = (rowState & DataGridViewElementStates.Displayed) != 0;
DataGridViewAutoSizeRowsModeInternal autoSizeRowsModeInternal = (DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode;
bool autoSizeRow = false;
// Auto size row if needed
if (autoSizeRowsModeInternal != DataGridViewAutoSizeRowsModeInternal.None &&
!((autoSizeRowsModeInternal & DataGridViewAutoSizeRowsModeInternal.DisplayedRows) != 0 && !rowDisplayed))
{
// this call may unshare the row.
int rowHeight = this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
this.Rows.SharedRow(rowIndex).CachedThickness = rowHeight;
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), false /*fixedWidth*/, true /*internalAutosizing*/);
autoSizeRow = true;
}
// Auto size columms also if needed
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFilter = DataGridViewAutoSizeColumnCriteriaInternal.AllRows;
if (rowDisplayed)
{
autoSizeColumnCriteriaFilter |= DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows;
}
bool columnAutoSized;
if (this.Rows.GetRowCount(DataGridViewElementStates.Visible) > 1)
{
// Columns can only expand, and not collapse.
columnAutoSized = AdjustExpandingColumns(autoSizeColumnCriteriaFilter, rowIndex);
}
else
{
columnAutoSized = AutoResizeAllVisibleColumnsInternal(autoSizeColumnCriteriaFilter, true /*fixedHeight*/);
}
bool fixedColumnHeadersHeight = this.ColumnHeadersHeightSizeMode != DataGridViewColumnHeadersHeightSizeMode.AutoSize;
bool rowHeadersAutoSize = this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.EnableResizing &&
this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.DisableResizing;
if (!rowHeadersAutoSize && !columnAutoSized)
{
// No need to autosize the column headers when the row headers and columns don't change.
fixedColumnHeadersHeight = true;
}
// Auto size row headers
if (rowHeadersAutoSize)
{
AutoResizeRowHeadersWidth(rowIndex, this.rowHeadersWidthSizeMode, fixedColumnHeadersHeight, true /*fixedRowsHeight*/);
}
// Auto size column headers
if (!fixedColumnHeadersHeight)
{
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
if (autoSizeRow)
{
// Second round of row autosizing
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (rowHeadersAutoSize && !fixedColumnHeadersHeight)
{
// Second round of row headers autosizing
AutoResizeRowHeadersWidth(rowIndex, this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, true /*fixedRowsHeight*/);
}
}
}
internal void OnAddedRows_PreNotification(DataGridViewRow[] dataGridViewRows)
{
// Note: no row can be added that breaks the frozen row packing on the top
foreach(DataGridViewRow dataGridViewRow in dataGridViewRows)
{
OnAddedRow_PreNotification(dataGridViewRow.Index);
}
}
internal void OnAddedRows_PostNotification(DataGridViewRow[] dataGridViewRows)
{
foreach (DataGridViewRow dataGridViewRow in dataGridViewRows)
{
OnAddedRow_PostNotification(dataGridViewRow.Index);
}
}
internal void OnAddingColumn(DataGridViewColumn dataGridViewColumn)
{
// throw an exception if the column to be added breaks the rules
if (dataGridViewColumn == null)
{
throw new ArgumentNullException("dataGridViewColumn");
}
if (dataGridViewColumn.DataGridView != null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_ColumnAlreadyBelongsToDataGridView));
}
if (!this.InInitialization &&
dataGridViewColumn.SortMode == DataGridViewColumnSortMode.Automatic &&
(this.SelectionMode == DataGridViewSelectionMode.FullColumnSelect ||
this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridViewColumn_SortModeAndSelectionModeClash, DataGridViewColumnSortMode.Automatic.ToString(), this.SelectionMode.ToString()));
}
if (dataGridViewColumn.Visible)
{
// Note that dataGridViewColumn.DataGridView is set later on, so dataGridViewColumn.InheritedAutoSizeMode should not be used
// Make sure the column does not autosize based only on header while column headers are invisible
if (!this.ColumnHeadersVisible &&
(dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.ColumnHeader || (dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.NotSet && this.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.ColumnHeader)))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddAutoSizedColumn));
}
// Make sure the column is not frozen and auto fills
if (dataGridViewColumn.Frozen &&
(dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.Fill || (dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.NotSet && this.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.Fill)))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddAutoFillColumn));
}
// UsedFillWeight values need to be updated
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
}
// Make sure the sum of the column weights does not exceed ushort.MaxValue
float weightSum = this.Columns.GetColumnsFillWeight(DataGridViewElementStates.None) + dataGridViewColumn.FillWeight;
if (weightSum > (float)ushort.MaxValue)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_WeightSumCannotExceedLongMaxValue, (ushort.MaxValue).ToString(CultureInfo.CurrentCulture)));
}
// check for correctness of frozen state - throws exception if state is incorrect.
CorrectColumnFrozenState(dataGridViewColumn, this.Columns.Count);
// prepare the existing rows by appending cells of correct type
if (this.Rows.Count > 0)
{
// Only require a default cell type when there are rows to fill
if (dataGridViewColumn.CellType == null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddUntypedColumn));
}
if (dataGridViewColumn.CellTemplate.DefaultNewRowValue != null && this.newRowIndex != -1)
{
// New row needs to be unshared before addition of new cell with a Value != null
DataGridViewRow newRow = this.Rows[this.newRowIndex];
}
int newColumnCount = this.Columns.Count + 1;
try
{
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Cells.Count < newColumnCount)
{
DataGridViewCell dataGridViewCellNew = (DataGridViewCell)dataGridViewColumn.CellTemplate.Clone();
dataGridViewRow.Cells.AddInternal(dataGridViewCellNew);
if (rowIndex == this.newRowIndex)
{
dataGridViewCellNew.SetValueInternal(rowIndex, dataGridViewCellNew.DefaultNewRowValue);
}
dataGridViewCellNew.DataGridViewInternal = this;
dataGridViewCellNew.OwningRowInternal = dataGridViewRow;
dataGridViewCellNew.OwningColumnInternal = dataGridViewColumn;
}
}
}
catch
{
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Cells.Count == newColumnCount)
{
dataGridViewRow.Cells.RemoveAtInternal(newColumnCount - 1);
}
else
{
Debug.Assert(dataGridViewRow.Cells.Count < newColumnCount);
break;
}
}
throw;
}
}
}
[
SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops") // not legitimate
]
internal void OnAddingColumns(DataGridViewColumn[] dataGridViewColumns)
{
// Make sure the sum of the column weights does not exceed ushort.MaxValue
float weightSum = this.Columns.GetColumnsFillWeight(DataGridViewElementStates.None);
Debug.Assert(weightSum <= (float)ushort.MaxValue);
// throw an exception if any of the columns to be added breaks the rules
Debug.Assert(dataGridViewColumns != null);
foreach (DataGridViewColumn dataGridViewColumn in dataGridViewColumns)
{
if (dataGridViewColumn == null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_AtLeastOneColumnIsNull));
}
if (dataGridViewColumn.DataGridView != null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_ColumnAlreadyBelongsToDataGridView));
}
// Only require a default cell type when there are rows to fill
if (this.Rows.Count > 0 && dataGridViewColumn.CellType == null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddUntypedColumn));
}
if (!this.InInitialization &&
dataGridViewColumn.SortMode == DataGridViewColumnSortMode.Automatic &&
(this.SelectionMode == DataGridViewSelectionMode.FullColumnSelect ||
this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridViewColumn_SortModeAndSelectionModeClash, DataGridViewColumnSortMode.Automatic.ToString(), this.SelectionMode.ToString()));
}
if (dataGridViewColumn.Visible)
{
// Note that dataGridViewColumn.DataGridView is set later on, so dataGridViewColumn.InheritedAutoSizeMode should not be used
// Make sure the column does not autosize based only on header while column headers are invisible
if (!this.ColumnHeadersVisible &&
(dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.ColumnHeader || (dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.NotSet && this.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.ColumnHeader)))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddAutoSizedColumn));
}
// Make sure the column is not frozen and auto fills
if (dataGridViewColumn.Frozen &&
(dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.Fill || (dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.NotSet && this.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.Fill)))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddAutoFillColumn));
}
// UsedFillWeight values need to be updated
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
}
weightSum += dataGridViewColumn.FillWeight;
if (weightSum > (float)ushort.MaxValue)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_WeightSumCannotExceedLongMaxValue, (ushort.MaxValue).ToString(CultureInfo.CurrentCulture)));
}
}
Debug.Assert(weightSum <= (float)ushort.MaxValue);
// make sure no two columns are identical
int columnCount = dataGridViewColumns.Length;
for (int column1 = 0; column1 < columnCount - 1; column1++)
{
for (int column2 = column1 + 1; column2 < columnCount; column2++)
{
if (dataGridViewColumns[column1] == dataGridViewColumns[column2])
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddIdenticalColumns));
}
}
}
// check for correctness of frozen states - throws exception if any state is incorrect.
CorrectColumnFrozenStates(dataGridViewColumns);
// prepare the existing rows by appending cells of correct type
if (this.Rows.Count > 0)
{
foreach (DataGridViewColumn dataGridViewColumn in dataGridViewColumns)
{
Debug.Assert(dataGridViewColumn.CellType != null);
if (dataGridViewColumn.CellTemplate.DefaultNewRowValue != null && this.newRowIndex != -1)
{
// New row needs to be unshared before addition of new cell with a Value != null
DataGridViewRow newRow = this.Rows[this.newRowIndex];
break;
}
}
int previousColumnCount = this.Columns.Count;
int addedColumnCount = 0;
try
{
foreach (DataGridViewColumn dataGridViewColumn in dataGridViewColumns)
{
addedColumnCount++;
Debug.Assert(dataGridViewColumn.CellType != null);
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Cells.Count < previousColumnCount + addedColumnCount)
{
DataGridViewCell dataGridViewCellNew = (DataGridViewCell)dataGridViewColumn.CellTemplate.Clone();
int indexCell = dataGridViewRow.Cells.AddInternal(dataGridViewCellNew);
if (rowIndex == this.newRowIndex)
{
dataGridViewCellNew.Value = dataGridViewCellNew.DefaultNewRowValue;
}
dataGridViewCellNew.DataGridViewInternal = this;
dataGridViewCellNew.OwningRowInternal = dataGridViewRow;
dataGridViewCellNew.OwningColumnInternal = dataGridViewColumn;
}
}
}
}
catch
{
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
while (dataGridViewRow.Cells.Count > previousColumnCount)
{
dataGridViewRow.Cells.RemoveAtInternal(dataGridViewRow.Cells.Count - 1);
}
}
throw;
}
}
}
internal void OnAddingRow(DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, bool checkFrozenState)
{
// Note dataGridViewRow.DataGridView != null for duplication of shared rows.
// throw an exception if the row to be added breaks the rules
if (dataGridViewRow == null)
{
throw new ArgumentNullException("dataGridViewRow");
}
// !Do not check for dataGridViewRow.Selected flag. Caller does it instead!
// !Do not check for dataGridViewRow.DataGridView != null. Caller does it instead!
if (checkFrozenState)
{
// check for correctness of frozen state - throws exception if state is incorrect.
CorrectRowFrozenState(dataGridViewRow, rowState, this.Rows.Count);
}
if (this.ReadOnly && dataGridViewRow.DataGridView == null && dataGridViewRow.ReadOnly)
{
// Clear the superfluous flag since the whole dataGridView is read-only
dataGridViewRow.ReadOnly = false;
}
int columnIndex = 0;
foreach (DataGridViewColumn dataGridViewColumn in this.Columns)
{
DataGridViewCell dataGridViewCell = dataGridViewRow.Cells[columnIndex];
if ((this.ReadOnly || dataGridViewColumn.ReadOnly) && dataGridViewCell.StateIncludes(DataGridViewElementStates.ReadOnly))
{
// Clear superfluous flag since the whole dataGridView or column is ReadOnly
dataGridViewCell.ReadOnlyInternal = false;
}
columnIndex++;
}
}
internal void OnAddingRows(DataGridViewRow[] dataGridViewRows, bool checkFrozenStates)
{
// throw an exception if any of the rows to be added breaks the rules
Debug.Assert(dataGridViewRows != null);
foreach (DataGridViewRow dataGridViewRow in dataGridViewRows)
{
if (dataGridViewRow == null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_AtLeastOneRowIsNull));
}
if (dataGridViewRow.DataGridView != null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_RowAlreadyBelongsToDataGridView));
}
if (dataGridViewRow.Selected)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridViewRowCollection_CannotAddOrInsertSelectedRow));
}
if (dataGridViewRow.Cells.Count > this.Columns.Count)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridViewRowCollection_TooManyCells));
}
}
// make sure no two rows are identical
int rowCount = dataGridViewRows.Length;
for (int row1 = 0; row1 < rowCount - 1; row1++)
{
for (int row2 = row1 + 1; row2 < rowCount; row2++)
{
if (dataGridViewRows[row1] == dataGridViewRows[row2])
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddIdenticalRows));
}
}
}
if (checkFrozenStates)
{
Debug.Assert(!this.AllowUserToAddRowsInternal);
CorrectRowFrozenStates(dataGridViewRows, this.Rows.Count /*rowIndexInserted*/);
}
foreach (DataGridViewRow dataGridViewRow in dataGridViewRows)
{
CompleteCellsCollection(dataGridViewRow);
OnAddingRow(dataGridViewRow, dataGridViewRow.State, false /*checkFrozenState*/);
}
}
internal void OnAdvancedBorderStyleChanged(DataGridViewAdvancedBorderStyle dgvabs)
{
if (!this.dataGridViewOper[DATAGRIDVIEWOPER_inBorderStyleChange])
{
if (dgvabs == this.advancedCellBorderStyle)
{
OnCellBorderStyleChanged(EventArgs.Empty);
}
else if (dgvabs == this.advancedColumnHeadersBorderStyle)
{
OnColumnHeadersBorderStyleChanged(EventArgs.Empty);
}
else if (dgvabs == this.advancedRowHeadersBorderStyle)
{
OnRowHeadersBorderStyleChanged(EventArgs.Empty);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAllowUserToAddRowsChanged"]/*' />
protected virtual void OnAllowUserToAddRowsChanged(EventArgs e)
{
PushAllowUserToAddRows();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWALLOWUSERTOADDROWSCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAllowUserToDeleteRowsChanged"]/*' />
protected virtual void OnAllowUserToDeleteRowsChanged(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWALLOWUSERTODELETEROWSCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAllowUserToOrderColumnsChanged"]/*' />
protected virtual void OnAllowUserToOrderColumnsChanged(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWALLOWUSERTOORDERCOLUMNSCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAllowUserToResizeColumnsChanged"]/*' />
protected virtual void OnAllowUserToResizeColumnsChanged(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWALLOWUSERTORESIZECOLUMNSCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAllowUserToResizeRowsChanged"]/*' />
protected virtual void OnAllowUserToResizeRowsChanged(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWALLOWUSERTORESIZEROWSCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAlternatingRowsDefaultCellStyleChanged"]/*' />
protected virtual void OnAlternatingRowsDefaultCellStyleChanged(EventArgs e)
{
DataGridViewCellStyleChangedEventArgs dgvcsce = e as DataGridViewCellStyleChangedEventArgs;
if (dgvcsce != null && !dgvcsce.ChangeAffectsPreferredSize)
{
InvalidateData();
}
else
{
OnRowsGlobalAutoSize();
if (this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWALTERNATINGROWSDEFAULTCELLSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAutoGenerateColumnsChanged"]/*' />
protected virtual void OnAutoGenerateColumnsChanged(EventArgs e)
{
if (this.AutoGenerateColumns && this.DataSource != null)
{
// refresh the list of columns and the rows
RefreshColumnsAndRows();
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWAUTOGENERATECOLUMNSCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnAutoSizeColumnModeChanged(DataGridViewColumn dataGridViewColumn, DataGridViewAutoSizeColumnMode previousInheritedMode)
{
Debug.Assert(dataGridViewColumn != null);
DataGridViewAutoSizeColumnModeEventArgs dgvascme = new DataGridViewAutoSizeColumnModeEventArgs(dataGridViewColumn, previousInheritedMode);
OnAutoSizeColumnModeChanged(dgvascme);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAutoSizeColumnModeChanged"]/*' />
protected virtual void OnAutoSizeColumnModeChanged(DataGridViewAutoSizeColumnModeEventArgs e)
{
DataGridViewColumn dataGridViewColumn = e.Column;
if (e.Column == null)
{
throw new InvalidOperationException(SR.GetString(SR.InvalidNullArgument, "e.Column"));
}
DataGridViewAutoSizeColumnMode autoSizeColumnMode = dataGridViewColumn.InheritedAutoSizeMode;
Debug.Assert(autoSizeColumnMode != DataGridViewAutoSizeColumnMode.NotSet);
DataGridViewAutoSizeColumnMode previousInheritedMode = e.PreviousMode;
bool previousInheritedModeAutoSized = previousInheritedMode != DataGridViewAutoSizeColumnMode.Fill &&
previousInheritedMode != DataGridViewAutoSizeColumnMode.None &&
previousInheritedMode != DataGridViewAutoSizeColumnMode.NotSet;
if (autoSizeColumnMode == DataGridViewAutoSizeColumnMode.Fill ||
previousInheritedMode == DataGridViewAutoSizeColumnMode.Fill)
{
// UsedFillWeight values need to be updated
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
}
bool fixedHeight = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) == 0;
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.None)
{
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.Fill)
{
if (!previousInheritedModeAutoSized)
{
// Save current column width for later reuse
dataGridViewColumn.CachedThickness = dataGridViewColumn.Thickness;
}
AutoResizeColumnInternal(dataGridViewColumn.Index,
(DataGridViewAutoSizeColumnCriteriaInternal) autoSizeColumnMode,
fixedHeight);
}
}
else if (dataGridViewColumn.Thickness != dataGridViewColumn.CachedThickness && previousInheritedModeAutoSized)
{
// Restoring cached column width
dataGridViewColumn.ThicknessInternal = Math.Max(dataGridViewColumn.MinimumWidth, dataGridViewColumn.CachedThickness);
}
// Auto fill columns if needed
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
// Autosize rows and column headers if needed
if (!fixedHeight)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(dataGridViewColumn.Index, true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
// Column gets autosized with 1 degree of freedom this time.
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.None && autoSizeColumnMode != DataGridViewAutoSizeColumnMode.Fill)
{
AutoResizeColumnInternal(dataGridViewColumn.Index,
(DataGridViewAutoSizeColumnCriteriaInternal)autoSizeColumnMode,
true /*fixedHeight*/);
}
}
DataGridViewAutoSizeColumnModeEventHandler eh = this.Events[EVENT_DATAGRIDVIEWAUTOSIZECOLUMNMODECHANGED] as DataGridViewAutoSizeColumnModeEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAutoSizeColumnsModeChanged"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.PreviousModes is more precise than just e
protected virtual void OnAutoSizeColumnsModeChanged(DataGridViewAutoSizeColumnsModeEventArgs e)
{
DataGridViewAutoSizeColumnMode[] previousModes = e.PreviousModes;
if (previousModes == null)
{
throw new ArgumentNullException("e.PreviousModes");
}
if (previousModes.Length != this.Columns.Count)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_PreviousModesHasWrongLength));
}
foreach (DataGridViewColumn dataGridViewColumn in this.Columns)
{
if (dataGridViewColumn.Visible)
{
DataGridViewAutoSizeColumnMode autoSizeColumnMode = dataGridViewColumn.InheritedAutoSizeMode;
Debug.Assert(autoSizeColumnMode != DataGridViewAutoSizeColumnMode.NotSet);
DataGridViewAutoSizeColumnMode previousInheritedMode = previousModes[dataGridViewColumn.Index];
bool previousInheritedModeAutoSized = previousInheritedMode != DataGridViewAutoSizeColumnMode.Fill &&
previousInheritedMode != DataGridViewAutoSizeColumnMode.None &&
previousInheritedMode != DataGridViewAutoSizeColumnMode.NotSet;
if (autoSizeColumnMode == DataGridViewAutoSizeColumnMode.Fill ||
previousInheritedMode == DataGridViewAutoSizeColumnMode.Fill)
{
// UsedFillWeight values need to be updated
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
}
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.None)
{
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.Fill)
{
if (!previousInheritedModeAutoSized)
{
// Save current column width for later reuse
dataGridViewColumn.CachedThickness = dataGridViewColumn.Thickness;
}
AutoResizeColumnInternal(dataGridViewColumn.Index,
(DataGridViewAutoSizeColumnCriteriaInternal)autoSizeColumnMode,
(((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) == 0 /*fixedHeight*/);
}
}
else if (dataGridViewColumn.Thickness != dataGridViewColumn.CachedThickness && previousInheritedModeAutoSized)
{
// Restoring cached column width
dataGridViewColumn.ThicknessInternal = Math.Max(dataGridViewColumn.MinimumWidth, dataGridViewColumn.CachedThickness);
}
}
}
// Auto fill columns if needed
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
// Autosize rows and column headers if needed
if ((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
// Second pass of column autosizing with 1 degree of freedom
foreach (DataGridViewColumn dataGridViewColumn in this.Columns)
{
DataGridViewAutoSizeColumnMode autoSizeColumnMode = dataGridViewColumn.InheritedAutoSizeMode;
Debug.Assert(autoSizeColumnMode != DataGridViewAutoSizeColumnMode.NotSet);
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.None && autoSizeColumnMode != DataGridViewAutoSizeColumnMode.Fill)
{
AutoResizeColumnInternal(dataGridViewColumn.Index,
(DataGridViewAutoSizeColumnCriteriaInternal)autoSizeColumnMode,
true /*fixedHeight*/);
}
}
}
DataGridViewAutoSizeColumnsModeEventHandler eh = this.Events[EVENT_DATAGRIDVIEWAUTOSIZECOLUMNSMODECHANGED] as DataGridViewAutoSizeColumnsModeEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnAutoSizeRowsModeChanged"]/*' />
protected virtual void OnAutoSizeRowsModeChanged(DataGridViewAutoSizeModeEventArgs e)
{
if (this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
// restore cached rows thickness
RestoreRowsCachedThickness();
}
else
{
if (!e.PreviousModeAutoSized)
{
// Save the rows thickness for later reuse
// Note that only visible rows are affected, contrary to columns in OnAutoSizeColumnsModeChanged where all columns are affected.
for (int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
// this call may unshare the row.
int rowHeight = this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
this.Rows.SharedRow(rowIndex).CachedThickness = rowHeight;
}
}
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
DataGridViewAutoSizeModeEventHandler eh = this.Events[EVENT_DATAGRIDVIEWAUTOSIZEROWSMODECHANGED] as DataGridViewAutoSizeModeEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnBackgroundColorChanged"]/*' />
protected virtual void OnBackgroundColorChanged(EventArgs e)
{
InvalidateInside();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWBACKGROUNDCOLORCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnBandContextMenuStripChanged(DataGridViewBand dataGridViewBand)
{
DataGridViewColumn dataGridViewColumn = dataGridViewBand as DataGridViewColumn;
if (dataGridViewColumn != null)
{
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnContextMenuStripChanged(dgvce);
}
else
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs((DataGridViewRow) dataGridViewBand);
OnRowContextMenuStripChanged(dgvre);
}
}
internal void OnBandDefaultCellStyleChanged(DataGridViewBand dataGridViewBand)
{
DataGridViewColumn dataGridViewColumn = dataGridViewBand as DataGridViewColumn;
if (dataGridViewColumn != null)
{
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnDefaultCellStyleChanged(dgvce);
}
else
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs((DataGridViewRow) dataGridViewBand);
OnRowDefaultCellStyleChanged(dgvre);
}
}
internal void OnBandDividerThicknessChanged(DataGridViewBand dataGridViewBand)
{
DataGridViewColumn dataGridViewColumn = dataGridViewBand as DataGridViewColumn;
if (dataGridViewColumn != null)
{
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnDividerWidthChanged(dgvce);
}
else
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs((DataGridViewRow) dataGridViewBand);
OnRowDividerHeightChanged(dgvre);
}
}
internal void OnBandHeaderCellChanged(DataGridViewBand dataGridViewBand)
{
DataGridViewColumn dataGridViewColumn = dataGridViewBand as DataGridViewColumn;
if (dataGridViewColumn != null)
{
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnHeaderCellChanged(dgvce);
}
else
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs((DataGridViewRow) dataGridViewBand);
OnRowHeaderCellChanged(dgvre);
}
}
internal void OnBandMinimumThicknessChanged(DataGridViewBand dataGridViewBand)
{
DataGridViewColumn dataGridViewColumn = dataGridViewBand as DataGridViewColumn;
if (dataGridViewColumn != null)
{
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnMinimumWidthChanged(dgvce);
}
else
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs((DataGridViewRow) dataGridViewBand);
OnRowMinimumHeightChanged(dgvre);
}
}
internal void OnBandThicknessChanged(DataGridViewBand dataGridViewBand)
{
DataGridViewColumn dataGridViewColumn = dataGridViewBand as DataGridViewColumn;
if (dataGridViewColumn != null)
{
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnWidthChanged(dgvce);
}
else
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs((DataGridViewRow) dataGridViewBand);
OnRowHeightChanged(dgvre);
}
}
internal void OnBandThicknessChanging()
{
if (this.InAdjustFillingColumns)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAlterAutoFillColumnParameter));
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnBindingContextChanged"]/*' />
protected override void OnBindingContextChanged(EventArgs e)
{
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_inBindingContextChanged])
{
return;
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_inBindingContextChanged] = true;
try
{
if (this.dataConnection != null)
{
this.CurrentCell = null;
try
{
this.dataConnection.SetDataConnection(this.DataSource, this.DataMember);
}
catch (ArgumentException)
{
if (this.DesignMode)
{
// This is the minimal fix for vsw 527646.
// If the DataMember became invalid at DesignTime then set it to String.Empty,
// regenerate the column collection and DO NOT send BindingContextChanged event.
this.DataMember = String.Empty;
RefreshColumnsAndRows();
return;
}
else
{
throw;
}
}
RefreshColumnsAndRows();
base.OnBindingContextChanged(e);
if (this.dataConnection.CurrencyManager != null)
{
OnDataBindingComplete(ListChangedType.Reset);
}
}
else
{
base.OnBindingContextChanged(e);
}
}
finally
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_inBindingContextChanged] = false;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnBorderStyleChanged"]/*' />
protected virtual void OnBorderStyleChanged(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWBORDERSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCancelRowEdit"]/*' />
protected virtual void OnCancelRowEdit(QuestionEventArgs e)
{
QuestionEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCANCELROWEDIT] as QuestionEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellBeginEdit"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellBeginEdit(DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellCancelEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLBEGINEDIT] as DataGridViewCellCancelEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellBorderStyleChanged"]/*' />
protected virtual void OnCellBorderStyleChanged(EventArgs e)
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
Invalidate();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLBORDERSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellClickInternal(DataGridViewCellEventArgs e)
{
OnCellClick(e);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellClick"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellClick(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.ClickUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnClickInternal(e);
}
else
{
dataGridViewCell.OnClickInternal(e);
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLCLICK] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellCommonChange(int columnIndex, int rowIndex)
{
if (columnIndex == -1)
{
// row or topleft header characteristic has changed
OnRowHeaderGlobalAutoSize(rowIndex);
}
else
{
if (rowIndex == -1)
{
// column header characteristic has changed
OnColumnHeaderGlobalAutoSize(columnIndex);
}
else
{
// regular cell characteristic changed
InvalidateCellPrivate(columnIndex, rowIndex);
bool rowDisplayed = false;
if (rowIndex != -1)
{
rowDisplayed = (this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Displayed) != 0;
}
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal = (DataGridViewAutoSizeColumnCriteriaInternal)this.Columns[columnIndex].InheritedAutoSizeMode;
bool autoSizeColumn = (autoSizeColumnCriteriaInternal & DataGridViewAutoSizeColumnCriteriaInternal.AllRows) != 0;
if (rowDisplayed)
{
autoSizeColumn |= (autoSizeColumnCriteriaInternal & DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows) != 0;
}
bool autoSizeRow = (((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0;
if (autoSizeRow)
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), !autoSizeColumn /*fixedWidth*/, true /*internalAutosizing*/);
}
if (autoSizeColumn)
{
AutoResizeColumnInternal(columnIndex, autoSizeColumnCriteriaInternal, true /*fixedHeight*/);
if (autoSizeRow)
{
// Second round of row autosizing with 1 degree of freedom.
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), true /*fixedWidth*/, true /*internalAutosizing*/);
}
}
}
}
}
internal void OnCellContentClickInternal(DataGridViewCellEventArgs e)
{
OnCellContentClick(e);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellContentClick"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellContentClick(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.ContentClickUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnContentClickInternal(e);
}
else
{
dataGridViewCell.OnContentClickInternal(e);
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLCONTENTCLICK] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellContentDoubleClickInternal(DataGridViewCellEventArgs e)
{
OnCellContentDoubleClick(e);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellContentDoubleClick"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellContentDoubleClick(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.ContentDoubleClickUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnContentDoubleClickInternal(e);
}
else
{
dataGridViewCell.OnContentDoubleClickInternal(e);
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLCONTENTDOUBLECLICK] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellContextMenuStripChanged(DataGridViewCell dataGridViewCell)
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(dataGridViewCell);
OnCellContextMenuStripChanged(dgvce);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellContextMenuStripChanged"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellContextMenuStripChanged(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLCONTEXTMENUSTRIPCHANGED] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal ContextMenuStrip OnCellContextMenuStripNeeded(int columnIndex, int rowIndex, ContextMenuStrip contextMenuStrip)
{
DataGridViewCellContextMenuStripNeededEventArgs dgvccmsne = new DataGridViewCellContextMenuStripNeededEventArgs(columnIndex, rowIndex, contextMenuStrip);
OnCellContextMenuStripNeeded(dgvccmsne);
return dgvccmsne.ContextMenuStrip;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellContextMenuStripNeeded"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellContextMenuStripNeeded(DataGridViewCellContextMenuStripNeededEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellContextMenuStripNeededEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLCONTEXTMENUSTRIPNEEDED] as DataGridViewCellContextMenuStripNeededEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellDoubleClick"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellDoubleClick(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.DoubleClickUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnDoubleClickInternal(e);
}
else
{
dataGridViewCell.OnDoubleClickInternal(e);
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLDOUBLECLICK] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellEndEdit"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellEndEdit(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLENDEDIT] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellEnter(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex)
{
OnCellEnter(new DataGridViewCellEventArgs(columnIndex, rowIndex));
if (dataGridViewCell != null)
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
dataGridViewCell = null;
}
else
{
Debug.Assert(rowIndex < this.Rows.Count && columnIndex < this.Columns.Count);
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellEnter"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellEnter(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
try
{
this.noDimensionChangeCount++;
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLENTER] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
}
}
internal void OnCellErrorTextChanged(DataGridViewCell dataGridViewCell)
{
Debug.Assert(dataGridViewCell.RowIndex >= -1);
Debug.Assert(dataGridViewCell.ColumnIndex >= -1);
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(dataGridViewCell);
OnCellErrorTextChanged(dgvce);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellErrorTextChanged"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellErrorTextChanged(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
UpdateCellErrorText(e.ColumnIndex, e.RowIndex);
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLERRORTEXTCHANGED] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal string OnCellErrorTextNeeded(int columnIndex, int rowIndex, string errorText)
{
Debug.Assert(columnIndex >= 0);
Debug.Assert(rowIndex >= 0);
DataGridViewCellErrorTextNeededEventArgs dgvcetne = new DataGridViewCellErrorTextNeededEventArgs(columnIndex, rowIndex, errorText);
OnCellErrorTextNeeded(dgvcetne);
return dgvcetne.ErrorText;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellErrorTextNeeded"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellErrorTextNeeded(DataGridViewCellErrorTextNeededEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellErrorTextNeededEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLERRORTEXTNEEDED] as DataGridViewCellErrorTextNeededEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal DataGridViewCellFormattingEventArgs OnCellFormatting(int columnIndex, int rowIndex, object val, Type formattedValueType, DataGridViewCellStyle cellStyle)
{
DataGridViewCellFormattingEventArgs dgvcfe = new DataGridViewCellFormattingEventArgs(columnIndex,
rowIndex,
val,
formattedValueType,
cellStyle);
OnCellFormatting(dgvcfe);
return dgvcfe;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellFormatting"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellFormatting(DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellFormattingEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLFORMATTING] as DataGridViewCellFormattingEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellLeave(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex)
{
OnCellLeave(new DataGridViewCellEventArgs(columnIndex, rowIndex));
if (dataGridViewCell != null)
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
dataGridViewCell = null;
}
else
{
Debug.Assert(rowIndex < this.Rows.Count && columnIndex < this.Columns.Count);
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellLeave"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellLeave(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
try
{
this.noDimensionChangeCount++;
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLLEAVE] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellMouseClick"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellMouseClick(DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.MouseClickUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnMouseClickInternal(e);
}
else
{
dataGridViewCell.OnMouseClickInternal(e);
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_nextMouseUpIsDouble] = false;
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLMOUSECLICK] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellMouseDoubleClick"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellMouseDoubleClick(DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.MouseDoubleClickUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnMouseDoubleClickInternal(e);
}
else
{
dataGridViewCell.OnMouseDoubleClickInternal(e);
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_nextMouseUpIsDouble] = true;
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLMOUSEDOUBLECLICK] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellMouseDown"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellMouseDown(DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
// Only left clicks for now
Keys nModifier = ModifierKeys;
bool isControlDown = (nModifier & Keys.Control) == Keys.Control && (nModifier & Keys.Alt) == 0;
bool isShiftDown = (nModifier & Keys.Shift) == Keys.Shift;
bool isAltDown = (nModifier & Keys.Alt) == Keys.Alt;
Point ptGridCoord = ConvertCellToGridCoord(e.ColumnIndex, e.RowIndex, e.X, e.Y);
HitTestInfo hti = HitTest(ptGridCoord.X, ptGridCoord.Y);
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls] && e.Button == MouseButtons.Left)
{
Debug.Assert(hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar);
Debug.Assert(this.ptMouseDownCell.X == hti.col);
Debug.Assert(this.ptMouseDownCell.Y == hti.row);
switch (hti.typeInternal)
{
// Check for column/row (headers) resize
case DataGridViewHitTestTypeInternal.ColumnResizeLeft:
case DataGridViewHitTestTypeInternal.ColumnResizeRight:
case DataGridViewHitTestTypeInternal.RowResizeBottom:
case DataGridViewHitTestTypeInternal.RowResizeTop:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeLeft:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeRight:
case DataGridViewHitTestTypeInternal.RowHeadersResizeLeft:
case DataGridViewHitTestTypeInternal.RowHeadersResizeRight:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeTop:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeBottom:
case DataGridViewHitTestTypeInternal.ColumnHeadersResizeTop:
case DataGridViewHitTestTypeInternal.ColumnHeadersResizeBottom:
{
this.dataGridViewOper[DATAGRIDVIEWOPER_resizingOperationAboutToStart] = (e.Clicks == 1);
break;
}
}
}
try
{
if (e.RowIndex >= 0 && dataGridViewCell.MouseDownUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnMouseDownInternal(e);
}
else
{
dataGridViewCell.OnMouseDownInternal(e);
}
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLMOUSEDOWN] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls] && e.Button == MouseButtons.Left)
{
switch (hti.typeInternal)
{
// Check column resize
case DataGridViewHitTestTypeInternal.ColumnResizeLeft:
case DataGridViewHitTestTypeInternal.ColumnResizeRight:
{
int columnIndex = (hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeRight) ? hti.col : hti.adjacentCol;
Debug.Assert(this.Columns[columnIndex].Resizable == DataGridViewTriState.True);
if (e.Clicks == 1)
{
BeginMouseColumnResize(ptGridCoord.X, hti.mouseBarOffset, columnIndex);
}
break;
}
// Check row resize
case DataGridViewHitTestTypeInternal.RowResizeBottom:
case DataGridViewHitTestTypeInternal.RowResizeTop:
{
int rowIndex = (hti.typeInternal == DataGridViewHitTestTypeInternal.RowResizeBottom) ? hti.row : hti.adjacentRow;
if (e.Clicks == 1)
{
BeginRowResize(ptGridCoord.Y, hti.mouseBarOffset, rowIndex);
}
break;
}
// Check for column header mouse down
case DataGridViewHitTestTypeInternal.ColumnHeader:
case DataGridViewHitTestTypeInternal.ColumnHeaderLeft:
case DataGridViewHitTestTypeInternal.ColumnHeaderRight:
case DataGridViewHitTestTypeInternal.FirstColumnHeaderLeft:
{
if (isAltDown && this.AllowUserToOrderColumns &&
(this.SelectionMode == DataGridViewSelectionMode.FullColumnSelect ||
this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect))
{
BeginColumnRelocation(ptGridCoord.X, hti.col);
}
else
{
OnColumnHeaderMouseDown(hti, isShiftDown, isControlDown);
}
break;
}
// Check for row header mouse down
case DataGridViewHitTestTypeInternal.RowHeader:
{
OnRowHeaderMouseDown(hti, isShiftDown, isControlDown);
break;
}
// Check for cell mouse down
case DataGridViewHitTestTypeInternal.Cell:
{
OnCellMouseDown(hti, isShiftDown, isControlDown);
break;
}
// Check for top/left header mouse down
case DataGridViewHitTestTypeInternal.TopLeftHeader:
{
OnTopLeftHeaderMouseDown();
break;
}
// Check for row headers resize
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeLeft:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeRight:
case DataGridViewHitTestTypeInternal.RowHeadersResizeLeft:
case DataGridViewHitTestTypeInternal.RowHeadersResizeRight:
{
if (e.Clicks == 1)
{
BeginRowHeadersResize(ptGridCoord.X, hti.mouseBarOffset);
}
break;
}
// Check for column headers resize
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeTop:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeBottom:
case DataGridViewHitTestTypeInternal.ColumnHeadersResizeTop:
case DataGridViewHitTestTypeInternal.ColumnHeadersResizeBottom:
{
if (e.Clicks == 1)
{
BeginColumnHeadersResize(ptGridCoord.Y, hti.mouseBarOffset);
}
break;
}
}
// Make sure that there is a current cell after this mouse down event.
if (this.ptCurrentCell.X == -1)
{
MakeFirstDisplayedCellCurrentCell(true /*includeNewRow*/);
}
}
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_resizingOperationAboutToStart] = false;
}
}
private void OnCellMouseDown(HitTestInfo hti, bool isShiftDown, bool isControlDown)
{
Debug.Assert(hti.Type == DataGridViewHitTestType.Cell);
// Only commit cell if the target cell is different from the current one.
if (this.ptCurrentCell.X >= 0 &&
(this.ptCurrentCell.X != hti.col || this.ptCurrentCell.Y != hti.row))
{
Point ptOriginalCurrentCell = this.ptCurrentCell;
if (!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit,
this.ptCurrentCell.X != hti.col || this.ptCurrentCell.Y != hti.row /*forCurrentCellChange*/,
this.ptCurrentCell.Y != hti.row /*forCurrentRowChange*/))
{
// Return silently if validating/commit/abort failed
return;
}
if (this.ptCurrentCell != ptOriginalCurrentCell)
{
// VSWhidbey 492203. Somehow the fact that the current cell was committed altered the current cell value.
// To avoid unintentional multi-selections, we act as if Shift and Control keys were up.
isShiftDown = isControlDown = false;
}
}
if (hti.col >= this.Columns.Count)
{
DataGridViewColumn dataGridViewLastVisibleColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (this.ptCurrentCell.X == -1 && dataGridViewLastVisibleColumn != null)
{
// CurrentCell was reset because CommitEdit deleted column(s).
// Since the user clicked on a cell, we don't want to end up
// with no CurrentCell. We pick the last visible column in the grid.
hti.col = dataGridViewLastVisibleColumn.Index;
}
else
{
return;
}
}
if (hti.row >= this.Rows.Count)
{
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
if (this.ptCurrentCell.X == -1 && lastVisibleRowIndex != -1)
{
// CurrentCell was reset because CommitEdit deleted row(s).
// Since the user clicked on a 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'.
hti.row = lastVisibleRowIndex;
}
else
{
return;
}
}
bool select = true;
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
if (isControlDown &&
IsSharedCellSelected(this.Rows.SharedRow(hti.row).Cells[hti.col], hti.row) &&
(!isShiftDown || !this.MultiSelect))
{
select = false;
}
if (select)
{
if ((!this.MultiSelect || !isControlDown) && !(this.MultiSelect && isShiftDown))
{
Debug.Assert(this.MultiSelect || this.individualSelectedCells.Count <= 1);
RemoveIndividuallySelectedCells(hti.col, hti.row);
}
if (this.MultiSelect)
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect] = true;
}
if (isShiftDown)
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, hti.col,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, hti.row);
}
else
{
SetSelectedCellCore(hti.col, hti.row, true);
}
}
else
{
SetSelectedCellCore(hti.col, hti.row, true);
}
}
else
{
SetSelectedCellCore(hti.col, hti.row, false);
}
bool success = SetCurrentCellAddressCore(hti.col, hti.row, !isShiftDown, false, true);
Debug.Assert(success);
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
{
if (isControlDown && this.Columns[hti.col].Selected)
{
select = false;
}
if (select)
{
bool selectColumnRange = false;
this.trackColumn = hti.col;
this.trackColumnEdge = -1;
if (this.MultiSelect &&
isShiftDown &&
this.ptAnchorCell.X > -1 &&
this.Columns[this.ptAnchorCell.X].Selected)
{
selectColumnRange = true;
}
if (!this.MultiSelect || !isControlDown || isShiftDown)
{
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != hti.col)
{
// deselect currently selected column
SetSelectedColumnCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
if (this.MultiSelect && this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] = true;
}
if (selectColumnRange)
{
if (this.Columns.DisplayInOrder(this.ptAnchorCell.X, hti.col))
{
SelectColumnRange(this.ptAnchorCell.X, hti.col, true);
}
else
{
SelectColumnRange(hti.col, this.ptAnchorCell.X, true);
}
}
else if (!this.selectedBandIndexes.Contains(hti.col))
{
SetSelectedColumnCore(hti.col, true);
}
}
else
{
Debug.Assert(this.selectedBandIndexes.Contains(hti.col));
SetSelectedColumnCore(hti.col, false);
}
bool success = SetCurrentCellAddressCore(hti.col, hti.row, !isShiftDown, false, true);
Debug.Assert(success);
break;
}
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
if (isControlDown &&
(this.Columns[hti.col].Selected || IsSharedCellSelected(this.Rows.SharedRow(hti.row).Cells[hti.col], hti.row)) &&
(!isShiftDown || !this.MultiSelect))
{
select = false;
}
if (select)
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedColumnCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
RemoveIndividuallySelectedCells();
}
SetSelectedCellCore(hti.col, hti.row, true);
}
else
{
// this.MultiSelect == true
if (!isControlDown && !isShiftDown)
{
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (this.selectedBandIndexes.Count > 0)
{
SetSelectedColumnCore(this.selectedBandIndexes.HeadInt, false);
}
RemoveIndividuallySelectedCells(hti.col, hti.row);
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect] = true;
}
if (isShiftDown)
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, hti.col,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, hti.row);
}
else
{
SetSelectedCellCore(hti.col, hti.row, true);
}
}
}
else
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedColumnCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
SetSelectedCellCore(hti.col, hti.row, false);
}
}
else
{
SetSelectedCellCore(hti.col, hti.row, false);
}
}
bool success = SetCurrentCellAddressCore(hti.col, hti.row, !isShiftDown, false, true);
Debug.Assert(success);
break;
}
case DataGridViewSelectionMode.FullRowSelect:
{
if (isControlDown &&
((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Selected) != 0))
{
select = false;
}
if (select)
{
bool selectRowRange = false;
this.trackRow = hti.row;
this.trackRowEdge = -1;
if (this.MultiSelect &&
isShiftDown &&
this.ptAnchorCell.Y > -1 && (this.Rows.GetRowState(this.ptAnchorCell.Y) & DataGridViewElementStates.Selected) != 0)
{
selectRowRange = true;
}
if (!this.MultiSelect || !isControlDown || isShiftDown)
{
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != hti.row)
{
// deselect currently selected row
SetSelectedRowCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
if (this.MultiSelect && this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] = true;
}
if (selectRowRange)
{
if (hti.row >= this.ptAnchorCell.Y)
{
SelectRowRange(this.ptAnchorCell.Y, hti.row, true);
}
else
{
SelectRowRange(hti.row, this.ptAnchorCell.Y, true);
}
}
else if ((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Selected) == 0)
{
Debug.Assert(this.selectedBandIndexes.Contains(hti.row) ==
((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Selected) != 0));
SetSelectedRowCore(hti.row, true);
}
}
else
{
Debug.Assert(this.selectedBandIndexes.Contains(hti.row));
SetSelectedRowCore(hti.row, false);
}
bool success = SetCurrentCellAddressCore(hti.col, hti.row, !isShiftDown, false, true);
Debug.Assert(success);
break;
}
case DataGridViewSelectionMode.RowHeaderSelect:
{
if (isControlDown &&
(((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Selected) != 0) ||
IsSharedCellSelected(this.Rows.SharedRow(hti.row).Cells[hti.col], hti.row)) &&
(!isShiftDown || !this.MultiSelect))
{
select = false;
}
if (select)
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedRowCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
RemoveIndividuallySelectedCells();
}
SetSelectedCellCore(hti.col, hti.row, true);
}
else
{
// this.MultiSelect == true
if (!isControlDown && !isShiftDown)
{
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (this.selectedBandIndexes.Count > 0)
{
SetSelectedRowCore(this.selectedBandIndexes.HeadInt, false);
}
RemoveIndividuallySelectedCells(hti.col, hti.row);
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect] = true;
}
if (isShiftDown)
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, hti.col,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, hti.row);
}
else
{
SetSelectedCellCore(hti.col, hti.row, true);
}
}
}
else
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedRowCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
SetSelectedCellCore(hti.col, hti.row, false);
}
}
else
{
SetSelectedCellCore(hti.col, hti.row, false);
}
}
bool success = SetCurrentCellAddressCore(hti.col, hti.row, !isShiftDown, false, true);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
break;
}
}
}
finally
{
this.NoSelectionChangeCount--;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellMouseEnter"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellMouseEnter(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
this.ptMouseEnteredCell.X = e.ColumnIndex;
this.ptMouseEnteredCell.Y = e.RowIndex;
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.MouseEnterUnsharesRowInternal(e.RowIndex))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnMouseEnterInternal(e.RowIndex);
}
else
{
dataGridViewCell.OnMouseEnterInternal(e.RowIndex);
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLMOUSEENTER] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellMouseLeave"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellMouseLeave(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
this.ptMouseEnteredCell.X = -2;
this.ptMouseEnteredCell.Y = -2;
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.MouseLeaveUnsharesRowInternal(e.RowIndex))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnMouseLeaveInternal(e.RowIndex);
}
else
{
dataGridViewCell.OnMouseLeaveInternal(e.RowIndex);
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLMOUSELEAVE] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellMouseMove"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellMouseMove(DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.MouseMoveUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnMouseMoveInternal(e);
}
else
{
dataGridViewCell.OnMouseMoveInternal(e);
}
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLMOUSEMOVE] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (!this.dataGridViewState1[DATAGRIDVIEWSTATE1_scrolledSinceMouseDown] &&
!this.IsMouseOperationActive() &&
this.AllowUserToOrderColumns &&
this.SelectionMode != DataGridViewSelectionMode.FullColumnSelect &&
this.SelectionMode != DataGridViewSelectionMode.ColumnHeaderSelect &&
e.Button == MouseButtons.Left &&
this.ptMouseDownCell.Y == -1 &&
this.ptMouseDownCell.X >= 0 &&
this.ptMouseDownCell.X < this.Columns.Count)
{
Point ptGridCoord = ConvertCellToGridCoord(e.ColumnIndex, e.RowIndex, e.X, e.Y);
HitTestInfo hti = HitTest(ptGridCoord.X, ptGridCoord.Y);
Debug.Assert(hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar);
switch (hti.typeInternal)
{
// Check for column header mouse down
case DataGridViewHitTestTypeInternal.ColumnHeader:
case DataGridViewHitTestTypeInternal.ColumnHeaderLeft:
case DataGridViewHitTestTypeInternal.ColumnHeaderRight:
case DataGridViewHitTestTypeInternal.FirstColumnHeaderLeft:
{
Debug.Assert(!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls]);
if (Math.Abs(this.ptMouseDownGridCoord.X - ptGridCoord.X) >= DataGridView.DragSize.Width ||
Math.Abs(this.ptMouseDownGridCoord.Y - ptGridCoord.Y) >= DataGridView.DragSize.Height)
{
BeginColumnRelocation(this.ptMouseDownGridCoord.X, this.ptMouseDownCell.X);
}
break;
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellMouseUp"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellMouseUp(DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCell dataGridViewCell = GetCellInternal(e.ColumnIndex, e.RowIndex);
Debug.Assert(dataGridViewCell != null);
if (e.RowIndex >= 0 && dataGridViewCell.MouseUpUnsharesRowInternal(e))
{
DataGridViewRow dataGridViewRow = this.Rows[e.RowIndex];
GetCellInternal(e.ColumnIndex, e.RowIndex).OnMouseUpInternal(e);
}
else
{
dataGridViewCell.OnMouseUpInternal(e);
}
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLMOUSEUP] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellPainting"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected internal virtual void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellPaintingEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLPAINTING] as DataGridViewCellPaintingEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal DataGridViewCellParsingEventArgs OnCellParsing(int rowIndex, int columnIndex, object formattedValue, Type valueType, DataGridViewCellStyle cellStyle)
{
DataGridViewCellParsingEventArgs dgvcpe = new DataGridViewCellParsingEventArgs(rowIndex, columnIndex,
formattedValue,
valueType,
cellStyle);
OnCellParsing(dgvcpe);
return dgvcpe;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellParsing"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellParsing(DataGridViewCellParsingEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellParsingEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLPARSING] as DataGridViewCellParsingEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnCellSelectMouseMove(HitTestInfo hti)
{
Debug.Assert(this.MultiSelect);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if ((hti.col != this.ptCurrentCell.X || hti.row != this.ptCurrentCell.Y) &&
!CommitEditForOperation(hti.col, hti.row, true))
{
// Return silently if validating/commit/abort failed
return;
}
this.noSelectionChangeCount++;
try
{
if (this.ptAnchorCell.X == -1 || IsInnerCellOutOfBounds(hti.col, hti.row))
{
return;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, hti.col,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, hti.row);
if (hti.col != this.ptCurrentCell.X || hti.row != this.ptCurrentCell.Y)
{
bool success = SetCurrentCellAddressCore(hti.col, hti.row, false, false, false);
Debug.Assert(success);
}
}
finally
{
this.NoSelectionChangeCount--;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellStateChanged"]/*' />
protected virtual void OnCellStateChanged(DataGridViewCellStateChangedEventArgs e)
{
// At this point we assume that only the Selected state has an influence on the rendering of the cell.
// If there is a scenario where another state has an effect, then the dev will have to invalidate the cell by hand.
DataGridViewCell dataGridViewCell = e.Cell;
if (e.StateChanged == DataGridViewElementStates.Selected)
{
Debug.Assert(dataGridViewCell.RowIndex >= 0);
if (this.inBulkPaintCount == 0)
{
InvalidateCellPrivate(dataGridViewCell);
}
}
DataGridViewCellStateChangedEventHandler eh = Events[EVENT_DATAGRIDVIEWCELLSTATECHANGED] as DataGridViewCellStateChangedEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (e.StateChanged == DataGridViewElementStates.ReadOnly &&
this.ptCurrentCell.X == dataGridViewCell.ColumnIndex &&
this.ptCurrentCell.Y == dataGridViewCell.RowIndex &&
dataGridViewCell.RowIndex > -1 &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange])
{
VerifyImeRestrictedModeChanged();
if (!dataGridViewCell.ReadOnly &&
ColumnEditable(this.ptCurrentCell.X) &&
!this.IsCurrentCellInEditMode &&
(this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null)))
{
// Current cell becomes read/write. Enter editing mode.
BeginEditInternal(true /*selectAll*/);
}
}
}
internal void OnCellStyleChanged(DataGridViewCell dataGridViewCell)
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(dataGridViewCell);
OnCellStyleChanged(dgvce);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellStyleChanged"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellStyleChanged(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
OnCellCommonChange(e.ColumnIndex, e.RowIndex);
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLSTYLECHANGED] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellStyleContentChanged(DataGridViewCellStyle dataGridViewCellStyle, DataGridViewCellStyle.DataGridViewCellStylePropertyInternal property)
{
Debug.Assert(dataGridViewCellStyle != null);
switch (property)
{
case DataGridViewCellStyle.DataGridViewCellStylePropertyInternal.Font:
if ((dataGridViewCellStyle.Scope & DataGridViewCellStyleScopes.DataGridView) != 0 && this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientFont])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientFont] = false;
}
if ((dataGridViewCellStyle.Scope & DataGridViewCellStyleScopes.ColumnHeaders) != 0 && this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientColumnHeadersFont])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientColumnHeadersFont] = false;
}
if ((dataGridViewCellStyle.Scope & DataGridViewCellStyleScopes.RowHeaders) != 0 && this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientRowHeadersFont])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientRowHeadersFont] = false;
}
break;
case DataGridViewCellStyle.DataGridViewCellStylePropertyInternal.ForeColor:
if ((dataGridViewCellStyle.Scope & DataGridViewCellStyleScopes.DataGridView) != 0 && this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientForeColor])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientForeColor] = false;
}
break;
}
DataGridViewCellStyleContentChangedEventArgs dgvcscce = new DataGridViewCellStyleContentChangedEventArgs(dataGridViewCellStyle,
property != DataGridViewCellStyle.DataGridViewCellStylePropertyInternal.Color &&
property != DataGridViewCellStyle.DataGridViewCellStylePropertyInternal.ForeColor /*changeAffectsPreferredSize*/);
OnCellStyleContentChanged(dgvcscce);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellStyleContentChanged"]/*' />
protected virtual void OnCellStyleContentChanged(DataGridViewCellStyleContentChangedEventArgs e)
{
// We assume that when a color changes, it has no effect on the autosize of elements
bool repositionEditingControl = false;
if ((e.CellStyleScope & DataGridViewCellStyleScopes.Cell) == DataGridViewCellStyleScopes.Cell && (e.CellStyleScope & DataGridViewCellStyleScopes.DataGridView) == 0)
{
// Same processing as in OnDefaultCellStyleChanged
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = true;
OnGlobalAutoSize();
}
else
{
Invalidate();
}
}
if ((e.CellStyleScope & DataGridViewCellStyleScopes.Column) == DataGridViewCellStyleScopes.Column)
{
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = true;
OnColumnsGlobalAutoSize();
}
else
{
InvalidateData();
}
}
if ((e.CellStyleScope & DataGridViewCellStyleScopes.Row) == DataGridViewCellStyleScopes.Row && (e.CellStyleScope & DataGridViewCellStyleScopes.Rows) == 0 && (e.CellStyleScope & DataGridViewCellStyleScopes.AlternatingRows) == 0)
{
// Same processing as in OnRowsDefaultCellStyleChanged
InvalidateData();
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = true;
// Autosize rows if needed
if ((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
AdjustShrinkingRows(this.autoSizeRowsMode, false /*fixedWidth*/, true /*internalAutosizing*/);
}
// Auto size columms also if needed
// Impossible to figure out if DisplayedRows filter should be added or not. Adding it to be on the conservative side.
AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal.AllRows |
DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows,
true /*fixedHeight*/);
// Second round of rows autosizing
if ((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
}
}
if ((e.CellStyleScope & DataGridViewCellStyleScopes.DataGridView) == DataGridViewCellStyleScopes.DataGridView)
{
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = e.ChangeAffectsPreferredSize;
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = false;
// OnDefaultCellStyleChanged will reposition the editing control.
}
OnDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
if ((e.CellStyleScope & DataGridViewCellStyleScopes.ColumnHeaders) == DataGridViewCellStyleScopes.ColumnHeaders)
{
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = e.ChangeAffectsPreferredSize;
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = false;
// OnColumnHeadersDefaultCellStyleChanged will reposition the editing control.
}
OnColumnHeadersDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
if ((e.CellStyleScope & DataGridViewCellStyleScopes.RowHeaders) == DataGridViewCellStyleScopes.RowHeaders)
{
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = e.ChangeAffectsPreferredSize;
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = false;
// OnRowHeadersDefaultCellStyleChanged will reposition the editing control.
}
OnRowHeadersDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
if ((e.CellStyleScope & DataGridViewCellStyleScopes.Rows) == DataGridViewCellStyleScopes.Rows)
{
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = e.ChangeAffectsPreferredSize;
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = false;
// OnRowsDefaultCellStyleChanged will reposition the editing control.
}
OnRowsDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
if ((e.CellStyleScope & DataGridViewCellStyleScopes.AlternatingRows) == DataGridViewCellStyleScopes.AlternatingRows)
{
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = e.ChangeAffectsPreferredSize;
if (e.ChangeAffectsPreferredSize)
{
repositionEditingControl = false;
// OnAlternatingRowsDefaultCellStyleChanged will reposition the editing control.
}
OnAlternatingRowsDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
if (repositionEditingControl && this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
DataGridViewCellStyleContentChangedEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLSTYLECONTENTCHANGED] as DataGridViewCellStyleContentChangedEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellToolTipTextChanged(DataGridViewCell dataGridViewCell)
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(dataGridViewCell);
OnCellToolTipTextChanged(dgvce);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellToolTipTextChanged"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellToolTipTextChanged(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLTOOLTIPTEXTCHANGED] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal string OnCellToolTipTextNeeded(int columnIndex, int rowIndex, string toolTipText)
{
DataGridViewCellToolTipTextNeededEventArgs dgvctttne = new DataGridViewCellToolTipTextNeededEventArgs(columnIndex, rowIndex, toolTipText);
OnCellToolTipTextNeeded(dgvctttne);
return dgvctttne.ToolTipText;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellToolTipTextNeeded"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellToolTipTextNeeded(DataGridViewCellToolTipTextNeededEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellToolTipTextNeededEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLTOOLTIPTEXTNEEDED] as DataGridViewCellToolTipTextNeededEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellValidated(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex)
{
OnCellValidated(new DataGridViewCellEventArgs(columnIndex, rowIndex));
if (dataGridViewCell != null)
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
dataGridViewCell = null;
}
else
{
Debug.Assert(rowIndex < this.Rows.Count && columnIndex < this.Columns.Count);
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellValidated"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellValidated(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
try
{
this.noDimensionChangeCount++;
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLVALIDATED] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
}
}
internal bool OnCellValidating(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex, DataGridViewDataErrorContexts context)
{
DataGridViewCell currentCell = (dataGridViewCell == null) ? this.CurrentCellInternal : dataGridViewCell;
DataGridViewCellStyle dataGridViewCellStyle = currentCell.GetInheritedStyle(null, rowIndex, false);
object val = currentCell.GetValueInternal(rowIndex);
object editedFormattedValue = currentCell.GetEditedFormattedValue(val, rowIndex, ref dataGridViewCellStyle, context);
DataGridViewCellValidatingEventArgs dgvcfvce = new DataGridViewCellValidatingEventArgs(columnIndex, rowIndex, editedFormattedValue);
OnCellValidating(dgvcfvce);
if (dataGridViewCell != null)
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
dataGridViewCell = null;
}
else
{
Debug.Assert(rowIndex < this.Rows.Count && columnIndex < this.Columns.Count);
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
}
return dgvcfvce.Cancel;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellValidating"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellValidating(DataGridViewCellValidatingEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
try
{
this.noDimensionChangeCount++;
this.dataGridViewOper[DATAGRIDVIEWOPER_inCellValidating] = true;
DataGridViewCellValidatingEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLVALIDATING] as DataGridViewCellValidatingEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
this.dataGridViewOper[DATAGRIDVIEWOPER_inCellValidating] = false;
}
}
internal void OnCellValueChangedInternal(DataGridViewCellEventArgs e)
{
// For now, same effect as if the cell style had changed.
OnCellValueChanged(e);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellValueChanged"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellValueChanged(DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
OnCellCommonChange(e.ColumnIndex, e.RowIndex);
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLVALUECHANGED] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal object OnCellValueNeeded(int columnIndex, int rowIndex)
{
DataGridViewCellValueEventArgs dgvcve = this.CellValueEventArgs;
dgvcve.SetProperties(columnIndex, rowIndex, null);
OnCellValueNeeded(dgvcve);
return dgvcve.Value;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellValueNeeded"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellValueNeeded(DataGridViewCellValueEventArgs e)
{
if (e.ColumnIndex < 0 || e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex < 0 || e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
//#if DEBUG
// Some customer scenarios may result in accessing cell values while this.dataStoreAccessAllowed is false. This is bad practice,
// but since we're late in Whidbey, throwing an exception would be destabilizing our internal customers.
// Debug.Assert(this.dataStoreAccessAllowed);
//#endif
DataGridViewCellValueEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLVALUENEEDED] as DataGridViewCellValueEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnCellValuePushed(int columnIndex, int rowIndex, object value)
{
DataGridViewCellValueEventArgs dgvcve = this.CellValueEventArgs;
dgvcve.SetProperties(columnIndex, rowIndex, value);
OnCellValuePushed(dgvcve);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCellValuePushed"]/*' />
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] // e.ColumnIndex / e.RowIndex is more precise than just e
protected virtual void OnCellValuePushed(DataGridViewCellValueEventArgs e)
{
if (e.ColumnIndex < 0 || e.ColumnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("e.ColumnIndex");
}
if (e.RowIndex < 0 || e.RowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("e.RowIndex");
}
DataGridViewCellValueEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCELLVALUEPUSHED] as DataGridViewCellValueEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnClearedRows()
{
// Raise the RowStateChanged(Displayed->false) events
foreach (DataGridViewRow dataGridViewRow in this.lstRows)
{
if (dataGridViewRow.Displayed)
{
dataGridViewRow.DisplayedInternal = false;
DataGridViewRowStateChangedEventArgs dgvrsce = new DataGridViewRowStateChangedEventArgs(dataGridViewRow, DataGridViewElementStates.Displayed);
OnRowStateChanged(-1 /*rowIndex*/, dgvrsce);
}
}
this.lstRows.Clear();
}
internal void OnClearingColumns()
{
this.CurrentCell = null;
// Rows need to be cleared first. There cannot be rows without also having columns.
this.Rows.ClearInternal(false /*recreateNewRow*/);
// Reset sort related variables.
this.sortedColumn = null;
this.sortOrder = SortOrder.None;
// selectedBandIndexes, individualSelectedCells & individualReadOnlyCells cleared in OnClearingRows.
}
[
SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops") // Illegitimate report.
]
internal void OnClearingRows()
{
// Build a list of displayed rows in order to be able to raise their RowStateChanged(Displayed->false) events later on
this.lstRows.Clear();
int numDisplayedRows = this.displayedBandsInfo.NumDisplayedFrozenRows + this.displayedBandsInfo.NumDisplayedScrollingRows;
if (numDisplayedRows > 0)
{
this.lstRows.Capacity = numDisplayedRows;
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Displayed);
while (numDisplayedRows > 0 && rowIndex != -1)
{
this.lstRows.Add(this.Rows[rowIndex]);
numDisplayedRows--;
if (numDisplayedRows > 0)
{
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Displayed);
}
}
}
this.CurrentCell = null;
this.newRowIndex = -1;
this.dataGridViewState2[DATAGRIDVIEWSTATE2_raiseSelectionChanged] = this.selectedBandIndexes.Count > 0 ||
this.individualSelectedCells.Count > 0;
this.selectedBandIndexes.Clear();
if (this.selectedBandSnapshotIndexes != null)
{
this.selectedBandSnapshotIndexes.Clear();
}
this.individualSelectedCells.Clear();
this.individualReadOnlyCells.Clear();
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnAdded"]/*' />
protected virtual void OnColumnAdded(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNADDED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnCollectionChanged_PreNotification(CollectionChangeEventArgs ccea)
{
// we need to map columns w/ DataPropertyName to bound columns
if (this.DataSource != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inRefreshColumns])
{
if (ccea.Action == CollectionChangeAction.Add)
{
DataGridViewColumn dataGridViewColumn = (DataGridViewColumn)ccea.Element;
if (dataGridViewColumn.DataPropertyName.Length != 0)
{
MapDataGridViewColumnToDataBoundField(dataGridViewColumn);
}
}
else if (ccea.Action == CollectionChangeAction.Refresh)
{
for (int i = 0; i < this.Columns.Count; i++)
{
if (this.Columns[i].DataPropertyName.Length != 0)
{
MapDataGridViewColumnToDataBoundField(this.Columns[i]);
}
}
}
}
ResetUIState(false /*useRowShortcut*/, false /*computeVisibleRows*/);
}
internal void OnColumnCollectionChanged_PostNotification(DataGridViewColumn dataGridViewColumn)
{
if (this.Columns.Count != 0 && this.Rows.Count == 0)
{
if (this.DataSource != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inRefreshColumns])
{
// this will create the 'add new row' when AllowUserToAddRowsInternal == true
RefreshRows(true /*scrollIntoView*/);
}
else if (this.AllowUserToAddRowsInternal)
{
AddNewRow(false);
}
}
if (this.AutoSize && (dataGridViewColumn == null || dataGridViewColumn.Visible))
{
LayoutTransaction.DoLayout(this.ParentInternal, this, PropertyNames.Columns);
}
}
internal void OnColumnCommonChange(int columnIndex)
{
OnColumnGlobalAutoSize(columnIndex);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnContextMenuStripChanged"]/*' />
protected virtual void OnColumnContextMenuStripChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNCONTEXTMENUSTRIPCHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnDataPropertyNameChanged(DataGridViewColumn dataGridViewColumn)
{
OnColumnDataPropertyNameChanged(new DataGridViewColumnEventArgs(dataGridViewColumn));
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnDataPropertyNameChanged"]/*' />
protected virtual void OnColumnDataPropertyNameChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
// map the dataGridView column to some data field
if (this.DataSource != null && e.Column.DataPropertyName.Length != 0 && !this.dataGridViewOper[DATAGRIDVIEWOPER_inRefreshColumns])
{
MapDataGridViewColumnToDataBoundField(e.Column);
}
else if (this.DataSource != null && e.Column.DataPropertyName.Length == 0)
{
if (e.Column.IsDataBound)
{
e.Column.IsDataBoundInternal = false;
e.Column.BoundColumnIndex = -1;
e.Column.BoundColumnConverter = null;
InvalidateColumnInternal(e.Column.Index);
}
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNDATAPROPERTYNAMECHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnDefaultCellStyleChanged"]/*' />
protected virtual void OnColumnDefaultCellStyleChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
OnColumnGlobalAutoSize(e.Column.Index);
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNDEFAULTCELLSTYLECHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnDisplayIndexChanged(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnDisplayIndexChanged(dgvce);
}
internal void OnColumnDisplayIndexChanging(DataGridViewColumn dataGridViewColumn, int newDisplayIndex)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(newDisplayIndex != dataGridViewColumn.DisplayIndex);
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments])
{
// We are within columns display indexes adjustments. We do not allow changing display indexes while adjusting them.
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAlterDisplayIndexWithinAdjustments));
}
// Throws an exception if the requested move is illegal
CorrectColumnFrozenStatesForMove(dataGridViewColumn, newDisplayIndex);
try
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments] = true;
// Move is legal - let's adjust the affected display indexes.
if (newDisplayIndex < dataGridViewColumn.DisplayIndex)
{
// DisplayIndex decreases. All columns with newDisplayIndex <= DisplayIndex < dataGridViewColumn.DisplayIndex
// get their DisplayIndex incremented.
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (newDisplayIndex <= dataGridViewColumnTmp.DisplayIndex && dataGridViewColumnTmp.DisplayIndex < dataGridViewColumn.DisplayIndex)
{
dataGridViewColumnTmp.DisplayIndexInternal = dataGridViewColumnTmp.DisplayIndex + 1;
dataGridViewColumnTmp.DisplayIndexHasChanged = true; // OnColumnDisplayIndexChanged needs to be raised later on
}
}
}
else
{
// DisplayIndex increases. All columns with dataGridViewColumn.DisplayIndex < DisplayIndex <= newDisplayIndex
// get their DisplayIndex incremented.
foreach (DataGridViewColumn dataGridViewColumnTmp in this.Columns)
{
if (dataGridViewColumn.DisplayIndex < dataGridViewColumnTmp.DisplayIndex && dataGridViewColumnTmp.DisplayIndex <= newDisplayIndex)
{
dataGridViewColumnTmp.DisplayIndexInternal = dataGridViewColumnTmp.DisplayIndex - 1;
dataGridViewColumnTmp.DisplayIndexHasChanged = true; // OnColumnDisplayIndexChanged needs to be raised later on
}
}
}
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments] = false;
}
// Note that displayIndex of moved column is updated by caller.
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnDisplayIndexChanged"]/*' />
protected virtual void OnColumnDisplayIndexChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
Debug.Assert(this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments]);
#if DEBUG
Debug.Assert(this.Columns.VerifyColumnDisplayIndexes());
#endif
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNDISPLAYINDEXCHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnDisplayIndexChanged_PreNotification()
{
Debug.Assert(this.dataGridViewOper[DATAGRIDVIEWOPER_inDisplayIndexAdjustments]);
// column.DisplayIndex changed - this may require a complete re-layout of the control
this.Columns.InvalidateCachedColumnsOrder();
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
if (this.editingControl != null)
{
PositionEditingControl(true, true, false);
}
Invalidate(Rectangle.Union(this.layout.ColumnHeaders, this.layout.Data));
}
internal void OnColumnDisplayIndexChanged_PostNotification()
{
// Notifications for adjusted display indexes.
FlushDisplayIndexChanged(true /*raiseEvent*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnDividerDoubleClick"]/*' />
protected virtual void OnColumnDividerDoubleClick(DataGridViewColumnDividerDoubleClickEventArgs e)
{
DataGridViewColumnDividerDoubleClickEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNDIVIDERDOUBLECLICK] as DataGridViewColumnDividerDoubleClickEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (!e.Handled && e.Button == MouseButtons.Left && e.ColumnIndex < this.Columns.Count)
{
if (e.ColumnIndex == -1)
{
AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders,
true /*fixedColumnHeadersHeight*/,
true /*fixedRowsHeight*/);
}
else
{
DataGridViewAutoSizeColumnMode inheritedAutoSizeMode = this.Columns[e.ColumnIndex].InheritedAutoSizeMode;
if (inheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.None || inheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
AutoResizeColumnInternal(e.ColumnIndex, DataGridViewAutoSizeColumnCriteriaInternal.Header | DataGridViewAutoSizeColumnCriteriaInternal.AllRows, true /*fixedHeight*/);
}
else
{
AutoResizeColumnInternal(e.ColumnIndex, (DataGridViewAutoSizeColumnCriteriaInternal)inheritedAutoSizeMode, true /*fixedHeight*/);
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnDividerWidthChanged"]/*' />
protected virtual void OnColumnDividerWidthChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
OnColumnGlobalAutoSize(e.Column.Index);
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNDIVIDERWIDTHCHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnFillWeightChanged(DataGridViewColumn dataGridViewColumn)
{
if (dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
// UsedFillWeight properties need to be re-evaluated
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
// Adjust filling columns based on new weight of this column
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
}
}
internal void OnColumnFillWeightChanging(DataGridViewColumn dataGridViewColumn, float fillWeight)
{
if (this.InAdjustFillingColumns)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAlterAutoFillColumnParameter));
}
// Make sure the sum of the column weights does not exceed ushort.MaxValue
float weightSum = this.Columns.GetColumnsFillWeight(DataGridViewElementStates.None) - dataGridViewColumn.FillWeight + fillWeight;
if (weightSum > (float)ushort.MaxValue)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_WeightSumCannotExceedLongMaxValue, (ushort.MaxValue).ToString(CultureInfo.CurrentCulture)));
}
}
private void OnColumnGlobalAutoSize(int columnIndex)
{
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count);
if (!this.Columns[columnIndex].Visible)
{
return;
}
InvalidateColumnInternal(columnIndex);
if (this.noAutoSizeCount > 0)
{
return;
}
bool fixedHeight = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) == 0;
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal = (DataGridViewAutoSizeColumnCriteriaInternal)this.Columns[columnIndex].InheritedAutoSizeMode;
if (autoSizeColumnCriteriaInternal != DataGridViewAutoSizeColumnCriteriaInternal.None &&
autoSizeColumnCriteriaInternal != DataGridViewAutoSizeColumnCriteriaInternal.Fill)
{
AutoResizeColumnInternal(columnIndex, autoSizeColumnCriteriaInternal, fixedHeight);
}
// Autosize rows and column headers if needed
if (!fixedHeight)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(columnIndex, true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
if (!fixedHeight &&
autoSizeColumnCriteriaInternal != DataGridViewAutoSizeColumnCriteriaInternal.None &&
autoSizeColumnCriteriaInternal != DataGridViewAutoSizeColumnCriteriaInternal.Fill)
{
// Second round of column autosizing with 1 degree of freedom
AutoResizeColumnInternal(columnIndex, autoSizeColumnCriteriaInternal, true /*fixedHeight*/);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnHeaderCellChanged"]/*' />
protected virtual void OnColumnHeaderCellChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
OnColumnHeaderGlobalAutoSize(e.Column.Index);
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNHEADERCELLCHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnColumnHeaderGlobalAutoSize(int columnIndex)
{
if (!this.ColumnHeadersVisible)
{
return;
}
InvalidateCellPrivate(columnIndex, -1);
if (this.noAutoSizeCount > 0)
{
return;
}
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal = (DataGridViewAutoSizeColumnCriteriaInternal)this.Columns[columnIndex].InheritedAutoSizeMode;
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFiltered = autoSizeColumnCriteriaInternal & DataGridViewAutoSizeColumnCriteriaInternal.Header;
bool fixedColumnWidth = autoSizeColumnCriteriaFiltered == 0;
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(columnIndex, true /*fixedRowHeadersWidth*/, fixedColumnWidth);
}
if (!fixedColumnWidth)
{
Debug.Assert(autoSizeColumnCriteriaInternal != DataGridViewAutoSizeColumnCriteriaInternal.None);
Debug.Assert(autoSizeColumnCriteriaInternal != DataGridViewAutoSizeColumnCriteriaInternal.Fill);
bool fixedHeight = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) == 0;
AutoResizeColumnInternal(columnIndex, autoSizeColumnCriteriaInternal, fixedHeight);
if (!fixedHeight)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
// Second round of column autosizing with 1 degree of freedom
AutoResizeColumnInternal(columnIndex, autoSizeColumnCriteriaInternal, true /*fixedHeight*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
// Second round of column headers autosizing with 1 degree of freedom
AutoResizeColumnHeadersHeight(columnIndex, true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnHeaderMouseClick"]/*' />
protected virtual void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Left &&
this.SelectionMode != DataGridViewSelectionMode.FullColumnSelect &&
this.SelectionMode != DataGridViewSelectionMode.ColumnHeaderSelect)
{
DataGridViewColumn dataGridViewColumn = this.Columns[e.ColumnIndex];
if (CanSort(dataGridViewColumn))
{
ListSortDirection direction = ListSortDirection.Ascending;
if (this.sortedColumn == dataGridViewColumn)
{
Debug.Assert(this.sortOrder != SortOrder.None);
if (this.sortOrder == SortOrder.Ascending)
{
direction = ListSortDirection.Descending;
}
}
if ((this.DataSource == null) ||
(this.DataSource != null &&
(this.dataConnection.List is IBindingList) &&
((IBindingList) this.dataConnection.List).SupportsSorting &&
dataGridViewColumn.IsDataBound))
{
Sort(dataGridViewColumn, direction);
}
}
}
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNHEADERMOUSECLICK] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnHeaderMouseDoubleClick"]/*' />
protected virtual void OnColumnHeaderMouseDoubleClick(DataGridViewCellMouseEventArgs e)
{
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNHEADERMOUSEDOUBLECLICK] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnColumnHeaderMouseDown(HitTestInfo hti, bool isShiftDown, bool isControlDown)
{
Debug.Assert(hti.Type == DataGridViewHitTestType.ColumnHeader);
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
break;
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
bool select = true;
if (isControlDown && this.Columns[hti.col].Selected)
{
select = false;
}
if (select)
{
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (rowIndex > -1 && hti.col != this.ptCurrentCell.X)
{
// Make sure we will be able to scroll into view
int oldCurrentCellX = this.ptCurrentCell.X;
int oldCurrentCellY = this.ptCurrentCell.Y;
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.CurrentCellChange,
DataGridViewValidateCellInternal.Always /*validateCell*/,
true /*fireCellLeave*/,
true /*fireCellEnter*/,
rowIndex != this.ptCurrentCell.Y /*fireRowLeave*/,
rowIndex != this.ptCurrentCell.Y /*fireRowEnter*/,
false /*fireLeave*/,
this.EditMode != DataGridViewEditMode.EditOnEnter /*keepFocus*/,
true /*resetCurrentCell*/,
false /*resetAnchorCell*/))
{
// Just cancel operation silently instead of throwing InvalidOperationException
return;
}
if (rowIndex != oldCurrentCellY && oldCurrentCellY != -1)
{
DataGridViewCell dataGridViewCellTmp = null;
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
if (OnRowValidating(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY))
{
// Row validation was cancelled
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
OnRowEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY, true /*canCreateNewRow*/, true /*validationFailureOccurred*/);
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
OnCellEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
return;
}
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
OnRowValidated(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
}
}
if (IsColumnOutOfBounds(hti.col))
{
return;
}
bool selectColumnRange = false;
this.trackColumn = hti.col;
this.trackColumnEdge = -1;
if (this.MultiSelect &&
isShiftDown &&
this.ptAnchorCell.X > -1 &&
this.Columns[this.ptAnchorCell.X].Selected)
{
selectColumnRange = true;
}
if (!this.MultiSelect || !isControlDown || isShiftDown)
{
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != hti.col)
{
// deselect currently selected column
SetSelectedColumnCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
if (this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect)
{
RemoveIndividuallySelectedCells();
}
else
{
Debug.Assert(this.individualSelectedCells.Count == 0);
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
if (this.MultiSelect && this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] = true;
}
if (selectColumnRange)
{
if (this.Columns.DisplayInOrder(this.ptAnchorCell.X, hti.col))
{
SelectColumnRange(this.ptAnchorCell.X, hti.col, true);
}
else
{
SelectColumnRange(hti.col, this.ptAnchorCell.X, true);
}
}
else if (!this.selectedBandIndexes.Contains(hti.col))
{
SetSelectedColumnCore(hti.col, true);
}
// set current cell to the top most visible cell in the column
if (rowIndex != -1)
{
if (hti.col != this.ptCurrentCell.X)
{
if (IsInnerCellOutOfBounds(hti.col, rowIndex))
{
return;
}
bool success = ScrollIntoView(hti.col, rowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(hti.col, rowIndex))
{
return;
}
success = SetCurrentCellAddressCore(hti.col, rowIndex, !isShiftDown, false, true);
Debug.Assert(success);
}
else if (-1 != this.ptCurrentCell.X)
{
// Potentially have to give focus back to the current edited cell.
bool success = SetCurrentCellAddressCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false /*setAnchorCellAddress*/, false /*validateCurrentCell*/, false /*throughMouseClick*/);
Debug.Assert(success);
}
}
else
{
Debug.Assert(this.CurrentCellAddress == new Point(-1, -1));
}
}
else
{
Debug.Assert(this.selectedBandIndexes.Contains(hti.col));
SetSelectedColumnCore(hti.col, false);
}
break;
}
}
}
finally
{
this.NoSelectionChangeCount--;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnHeadersBorderStyleChanged"]/*' />
protected virtual void OnColumnHeadersBorderStyleChanged(EventArgs e)
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
Invalidate();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNHEADERSBORDERSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnHeadersDefaultCellStyleChanged"]/*' />
protected virtual void OnColumnHeadersDefaultCellStyleChanged(EventArgs e)
{
if (this.ColumnHeadersVisible)
{
Invalidate(Rectangle.Union(this.layout.TopLeftHeader, this.layout.ColumnHeaders));
DataGridViewCellStyleChangedEventArgs dgvcsce = e as DataGridViewCellStyleChangedEventArgs;
if (dgvcsce == null || dgvcsce.ChangeAffectsPreferredSize)
{
OnColumnHeadersGlobalAutoSize();
if (this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNHEADERSDEFAULTCELLSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnColumnHeadersGlobalAutoSize()
{
if (this.noAutoSizeCount > 0)
{
return;
}
bool fixedRowHeadersWidth = this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing ||
this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.DisableResizing;
bool fixedColumnHeadersHeight = this.ColumnHeadersHeightSizeMode != DataGridViewColumnHeadersHeightSizeMode.AutoSize;
if (!fixedColumnHeadersHeight)
{
AutoResizeColumnHeadersHeight(fixedRowHeadersWidth, false /*fixedColumnsWidth*/);
}
if (!fixedRowHeadersWidth)
{
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, false /*fixedRowsHeight*/);
}
// Autosize columns
bool columnAutoSized = AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal.Header, false /*fixedHeight*/);
if (!fixedRowHeadersWidth || columnAutoSized)
{
// Autosize rows
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (!fixedColumnHeadersHeight)
{
// Second round of column headers autosizing
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
if (!fixedRowHeadersWidth)
{
// Second round of row headers autosizing
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, true /*fixedRowsHeight*/);
}
// Second round of columns autosizing
AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal.Header, true /*fixedHeight*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnHeadersHeightChanged"]/*' />
protected virtual void OnColumnHeadersHeightChanged(EventArgs e)
{
if (this.editingControl != null)
{
PositionEditingControl(true, false, false);
}
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
OnColumnHeadersGlobalAutoSize();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNHEADERSHEIGHTCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnHeadersHeightSizeModeChanged"]/*' />
protected virtual void OnColumnHeadersHeightSizeModeChanged(DataGridViewAutoSizeModeEventArgs e)
{
if (this.columnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
if (!e.PreviousModeAutoSized)
{
// Save current column headers height for later reuse
this.cachedColumnHeadersHeight = this.ColumnHeadersHeight;
}
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
else if (e.PreviousModeAutoSized)
{
this.ColumnHeadersHeight = this.cachedColumnHeadersHeight;
}
DataGridViewAutoSizeModeEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNHEADERSHEIGHTSIZEMODECHANGED] as DataGridViewAutoSizeModeEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnHidden(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
if (dataGridViewColumn.Displayed)
{
dataGridViewColumn.DisplayedInternal = false;
DataGridViewColumnStateChangedEventArgs dgvrsce = new DataGridViewColumnStateChangedEventArgs(dataGridViewColumn, DataGridViewElementStates.Displayed);
OnColumnStateChanged(dgvrsce);
}
}
internal void OnColumnMinimumWidthChanging(DataGridViewColumn dataGridViewColumn, int minimumWidth)
{
if (dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill && dataGridViewColumn.Width < minimumWidth)
{
// Force the filled column's width to be minimumWidth
try
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
dataGridViewColumn.DesiredMinimumWidth = minimumWidth;
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
}
finally
{
dataGridViewColumn.DesiredMinimumWidth = 0;
}
Debug.Assert(dataGridViewColumn.Width == minimumWidth);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnMinimumWidthChanged"]/*' />
protected virtual void OnColumnMinimumWidthChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
if (e.Column.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
// Column's width may adjust smaller
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNMINIMUMWIDTHCHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnNameChanged(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnNameChanged(dgvce);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnNameChanged"]/*' />
protected virtual void OnColumnNameChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
// Check if the column name is used as is in the column header
DataGridViewColumn dataGridViewColumn = e.Column;
if (dataGridViewColumn.HasHeaderCell && dataGridViewColumn.HeaderCell.Value is string &&
String.Compare((string)dataGridViewColumn.HeaderCell.Value, dataGridViewColumn.Name, false, CultureInfo.InvariantCulture) == 0)
{
InvalidateCellPrivate(dataGridViewColumn.Index, -1);
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal = (DataGridViewAutoSizeColumnCriteriaInternal) dataGridViewColumn.InheritedAutoSizeMode;
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFiltered = autoSizeColumnCriteriaInternal & DataGridViewAutoSizeColumnCriteriaInternal.Header;
bool fixedColumnWidth = autoSizeColumnCriteriaFiltered == 0 || !this.ColumnHeadersVisible;
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(dataGridViewColumn.Index, true /*fixedRowHeadersWidth*/, fixedColumnWidth);
}
if (!fixedColumnWidth)
{
bool fixedHeight = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) == 0;
AutoResizeColumnInternal(dataGridViewColumn.Index, autoSizeColumnCriteriaInternal, fixedHeight);
if (!fixedHeight)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
// Second round of column autosizing
AutoResizeColumnInternal(dataGridViewColumn.Index, autoSizeColumnCriteriaInternal, true /*fixedHeight*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
// Second round of column headers autosizing
AutoResizeColumnHeadersHeight(dataGridViewColumn.Index, true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
}
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNNAMECHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnColumnRemoved(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(dataGridViewColumn.DataGridView == null);
OnColumnRemoved(new DataGridViewColumnEventArgs(dataGridViewColumn));
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnRemoved"]/*' />
protected virtual void OnColumnRemoved(DataGridViewColumnEventArgs e)
{
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNREMOVED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnColumnSelectMouseMove(HitTestInfo hti)
{
Debug.Assert(hti.col >= 0);
Debug.Assert(this.MultiSelect);
if (this.ptCurrentCell.X != -1 &&
hti.col != this.ptCurrentCell.X &&
!CommitEditForOperation(hti.col, this.ptCurrentCell.Y, true))
{
// Return silently if validating/commit/abort failed
return;
}
if (IsColumnOutOfBounds(hti.col))
{
return;
}
this.noSelectionChangeCount++;
try
{
if (this.trackColumnEdge >= 0 && (this.Columns.DisplayInOrder(this.trackColumn, this.trackColumnEdge) || this.trackColumnEdge == this.trackColumn) && this.Columns.DisplayInOrder(this.trackColumnEdge, hti.col))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[this.trackColumnEdge], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(dataGridViewColumn.Index, hti.col, true);
this.trackColumnEdge = hti.col;
}
else if (this.trackColumnEdge >= 0 && this.Columns.DisplayInOrder(this.trackColumn, this.trackColumnEdge) && this.Columns.DisplayInOrder(hti.col, this.trackColumnEdge) && (this.Columns.DisplayInOrder(this.trackColumn, hti.col) || hti.col == this.trackColumn))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[hti.col], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(dataGridViewColumn.Index, this.trackColumnEdge, false);
this.trackColumnEdge = hti.col;
}
else if (this.trackColumnEdge == -1 && this.Columns.DisplayInOrder(this.trackColumn, hti.col))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[this.trackColumn], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(dataGridViewColumn.Index, hti.col, true);
this.trackColumnEdge = hti.col;
}
else if (this.trackColumnEdge >= 0 && (this.Columns.DisplayInOrder(this.trackColumnEdge, this.trackColumn) || this.trackColumnEdge == this.trackColumn) && this.Columns.DisplayInOrder(hti.col, this.trackColumnEdge))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[this.trackColumnEdge], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(hti.col, dataGridViewColumn.Index, true);
this.trackColumnEdge = hti.col;
}
else if (this.trackColumnEdge >= 0 && this.Columns.DisplayInOrder(this.trackColumnEdge, this.trackColumn) && this.Columns.DisplayInOrder(this.trackColumnEdge, hti.col) && (this.Columns.DisplayInOrder(hti.col, this.trackColumn) || hti.col == this.trackColumn))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[hti.col], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(this.trackColumnEdge, dataGridViewColumn.Index, false);
this.trackColumnEdge = hti.col;
}
else if (this.trackColumnEdge == -1 && this.Columns.DisplayInOrder(hti.col, this.trackColumn))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[this.trackColumn], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(hti.col, dataGridViewColumn.Index, true);
this.trackColumnEdge = hti.col;
}
else if (this.trackColumnEdge >= 0 && this.Columns.DisplayInOrder(this.trackColumn, this.trackColumnEdge) && this.Columns.DisplayInOrder(hti.col, this.trackColumn))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[this.trackColumn], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(dataGridViewColumn.Index, this.trackColumnEdge, false);
dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[this.trackColumn], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(hti.col, dataGridViewColumn.Index, true);
this.trackColumnEdge = hti.col;
}
else if (this.trackColumnEdge >= 0 && this.Columns.DisplayInOrder(this.trackColumn, hti.col) && this.Columns.DisplayInOrder(this.trackColumnEdge, this.trackColumn))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[this.trackColumn], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(this.trackColumnEdge, dataGridViewColumn.Index, false);
dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[this.trackColumn], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectColumnRange(dataGridViewColumn.Index, hti.col, true);
this.trackColumnEdge = hti.col;
}
}
finally
{
this.NoSelectionChangeCount--;
}
if (this.ptCurrentCell.X != -1 && hti.col != this.ptCurrentCell.X)
{
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(hti.col))
{
return;
}
bool success = SetCurrentCellAddressCore(hti.col,
this.ptCurrentCell.Y,
false /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/);
Debug.Assert(success);
}
}
private void OnColumnsGlobalAutoSize()
{
InvalidateData();
if (this.noAutoSizeCount > 0)
{
return;
}
// Auto-size columms if needed
bool fixedHeight = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) == 0;
bool columnAutoSized = AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal.AllRows | DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows, fixedHeight);
// Autosize rows if needed
if (!fixedHeight)
{
if (columnAutoSized)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
// Second round of columns autosizing
AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal.AllRows | DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows, true /*fixedHeight*/);
}
}
internal void OnColumnSortModeChanged(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn != null);
DataGridViewColumnEventArgs dgvce = new DataGridViewColumnEventArgs(dataGridViewColumn);
OnColumnSortModeChanged(dgvce);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnSortModeChanged"]/*' />
protected virtual void OnColumnSortModeChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
DataGridViewColumn dataGridViewColumn = e.Column;
if (dataGridViewColumn.HasHeaderCell)
{
if (dataGridViewColumn.SortMode == DataGridViewColumnSortMode.NotSortable ||
(dataGridViewColumn.SortMode == DataGridViewColumnSortMode.Programmatic && this.SortedColumn == dataGridViewColumn))
{
dataGridViewColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
// This call will trigger OnSortGlyphDirectionChanged which in turn does
// this.sortedColumn = null; and InvalidateCellPrivate(e.Column.Index, -1);
}
// Potential resizing of the column headers and/or affected column.
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal = (DataGridViewAutoSizeColumnCriteriaInternal) dataGridViewColumn.InheritedAutoSizeMode;
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFiltered = autoSizeColumnCriteriaInternal & DataGridViewAutoSizeColumnCriteriaInternal.Header;
bool fixedColumnWidth = autoSizeColumnCriteriaFiltered == 0 || !this.ColumnHeadersVisible;
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(dataGridViewColumn.Index, true /*fixedRowHeadersWidth*/, fixedColumnWidth);
}
if (!fixedColumnWidth)
{
bool fixedHeight = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) == 0;
AutoResizeColumnInternal(dataGridViewColumn.Index, autoSizeColumnCriteriaInternal, fixedHeight);
if (!fixedHeight)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
// Second round of column autosizing
AutoResizeColumnInternal(dataGridViewColumn.Index, autoSizeColumnCriteriaInternal, true /*fixedHeight*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
// Second round of column headers autosizing
AutoResizeColumnHeadersHeight(dataGridViewColumn.Index, true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
}
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNSORTMODECHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnStateChanged"]/*' />
protected virtual void OnColumnStateChanged(DataGridViewColumnStateChangedEventArgs e)
{
// column.Frozen | .Visible changed - this may require a complete re-layout of the control
DataGridViewColumn dataGridViewColumn = e.Column;
switch (e.StateChanged)
{
// At this point we assume that only the Selected state has an influence on the rendering of the column.
// If there is a customer scenario where another state has an influence, the dev must invalidate the column by hand.
// case DataGridViewElementStates.ReadOnly:
// case DataGridViewElementStates.Resizable:
case DataGridViewElementStates.Selected:
if (dataGridViewColumn.Visible && this.inBulkPaintCount == 0)
{
InvalidateColumnInternal(dataGridViewColumn.Index);
}
break;
case DataGridViewElementStates.Frozen:
if (dataGridViewColumn.Visible)
{
if (dataGridViewColumn.Frozen)
{
// visible column became frozen
if (this.horizontalOffset >= dataGridViewColumn.Thickness)
{
Debug.Assert(this.Columns.DisplayInOrder(dataGridViewColumn.Index, this.displayedBandsInfo.FirstDisplayedScrollingCol));
this.horizontalOffset -= dataGridViewColumn.Thickness;
}
else
{
this.horizontalOffset = this.negOffset = 0;
}
}
else
{
// column was unfrozen - make it the first visible scrolling column if there is room
this.horizontalOffset = this.negOffset = 0;
}
if (this.horizScrollBar.Enabled)
{
this.horizScrollBar.Value = this.horizontalOffset;
}
// UsedFillWeight values need to be updated
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, true /*repositionEditingControl*/);
Invalidate();
}
break;
case DataGridViewElementStates.Visible:
if (!dataGridViewColumn.Visible && dataGridViewColumn.Displayed)
{
// Displayed column becomes invisible. Turns off the Displayed state.
dataGridViewColumn.DisplayedInternal = false;
}
// UsedFillWeight values need to be updated
this.dataGridViewState2[DATAGRIDVIEWSTATE2_usedFillWeightsDirty] = true;
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, true /*repositionEditingControl*/);
bool autoSizeRows = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0 ||
((((DataGridViewAutoSizeRowsModeInternal) this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.Header) != 0 &&
this.RowHeadersVisible);
bool autoSizeColumn = false;
DataGridViewAutoSizeColumnMode autoSizeColumnMode = dataGridViewColumn.InheritedAutoSizeMode;
Debug.Assert(autoSizeColumnMode != DataGridViewAutoSizeColumnMode.NotSet);
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.None &&
autoSizeColumnMode != DataGridViewAutoSizeColumnMode.Fill)
{
// Column autosizes
int width = dataGridViewColumn.ThicknessInternal;
if (dataGridViewColumn.Visible)
{
// Cache column's width before potential autosizing occurs
dataGridViewColumn.CachedThickness = width;
AutoResizeColumnInternal(dataGridViewColumn.Index, (DataGridViewAutoSizeColumnCriteriaInternal)autoSizeColumnMode, !autoSizeRows /*fixedHeight*/);
autoSizeColumn = true;
}
else if (width != dataGridViewColumn.CachedThickness)
{
// Columns that are made invisible in the collection take their non-autosized width
dataGridViewColumn.ThicknessInternal = Math.Max(dataGridViewColumn.MinimumWidth, dataGridViewColumn.CachedThickness);
}
}
if (autoSizeRows)
{
if (dataGridViewColumn.Visible)
{
AdjustExpandingRows(dataGridViewColumn.Index, true /*fixedWidth*/);
}
else
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (autoSizeColumn)
{
// Second round of column autosizing
AutoResizeColumnInternal(dataGridViewColumn.Index, (DataGridViewAutoSizeColumnCriteriaInternal)autoSizeColumnMode, true /*fixedHeight*/);
}
}
else
{
Invalidate();
}
break;
}
DataGridViewColumnStateChangedEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNSTATECHANGED] as DataGridViewColumnStateChangedEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (e.StateChanged == DataGridViewElementStates.ReadOnly &&
dataGridViewColumn.Index == this.ptCurrentCell.X &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange])
{
VerifyImeRestrictedModeChanged();
if (!dataGridViewColumn.ReadOnly &&
ColumnEditable(this.ptCurrentCell.X) &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.ReadOnly) == 0 &&
!this.IsCurrentCellInEditMode &&
(this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null)))
{
// Current column becomes read/write. Enter editing mode.
BeginEditInternal(true /*selectAll*/);
}
}
}
internal void OnColumnToolTipTextChanged(DataGridViewColumn dataGridViewColumn)
{
OnColumnToolTipTextChanged(new DataGridViewColumnEventArgs(dataGridViewColumn));
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnToolTipTextChanged"]/*' />
protected virtual void OnColumnToolTipTextChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNTOOLTIPTEXTCHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnColumnWidthChanged"]/*' />
protected virtual void OnColumnWidthChanged(DataGridViewColumnEventArgs e)
{
if (e.Column.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
this.Columns.InvalidateCachedColumnsWidths();
// don't do any layout logic if the handle was not created already
if (e.Column.Visible && this.IsHandleCreated)
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
Rectangle rightArea = this.layout.Data;
if (this.layout.ColumnHeadersVisible)
{
rightArea = Rectangle.Union(rightArea, this.layout.ColumnHeaders);
}
else if (this.SingleHorizontalBorderAdded)
{
rightArea.Y--;
rightArea.Height++;
}
if (rightArea.Width > 0 && rightArea.Height > 0)
{
int leftEdge = GetColumnXFromIndex(e.Column.Index);
if (this.RightToLeftInternal)
{
rightArea.Width -= rightArea.Right - leftEdge;
}
else
{
rightArea.Width -= leftEdge - rightArea.X;
rightArea.X = leftEdge;
}
if (rightArea.Width > 0 && rightArea.Height > 0)
{
Invalidate(rightArea);
}
}
if (this.editingControl != null)
{
PositionEditingControl(this.ptCurrentCell.X != e.Column.Index, true, false);
}
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
if (this.AutoSize)
{
LayoutTransaction.DoLayout(this.ParentInternal, this, PropertyNames.Columns);
}
}
DataGridViewColumnEventHandler eh = this.Events[EVENT_DATAGRIDVIEWCOLUMNWIDTHCHANGED] as DataGridViewColumnEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (!this.InAdjustFillingColumns)
{
// Autosize rows and column headers if needed
OnColumnGlobalAutoSize(e.Column.Index);
}
}
internal void OnCommonCellContentClick(int columnIndex, int rowIndex, bool doubleClick)
{
if (this.ptMouseDownCell.X == -2 ||
(this.dataGridViewState2[DATAGRIDVIEWSTATE2_cellMouseDownInContentBounds] &&
this.ptMouseDownCell.X == columnIndex && this.ptMouseDownCell.Y == rowIndex &&
(this.ptMouseDownCell.X == -1 || this.ptMouseDownCell.Y == -1 ||
(columnIndex == this.ptCurrentCell.X && rowIndex == this.ptCurrentCell.Y))))
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(columnIndex, rowIndex);
if (doubleClick)
{
OnCellContentDoubleClick(dgvce);
}
else
{
OnCellContentClick(dgvce);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCurrentCellChanged"]/*' />
protected virtual void OnCurrentCellChanged(EventArgs e)
{
VerifyImeRestrictedModeChanged();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWCURRENTCELLCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCurrentCellDirtyStateChanged"]/*' />
protected virtual void OnCurrentCellDirtyStateChanged(EventArgs e)
{
if (this.RowHeadersVisible && this.ShowEditingIcon)
{
// Force the pencil to appear in the row header
Debug.Assert(this.ptCurrentCell.Y >= 0);
InvalidateCellPrivate(-1, this.ptCurrentCell.Y);
}
if (this.IsCurrentCellDirty && this.newRowIndex == this.ptCurrentCell.Y)
{
Debug.Assert(this.newRowIndex != -1);
Debug.Assert(this.AllowUserToAddRowsInternal);
// First time the 'new' row gets edited.
// It becomes a regular row and a new 'new' row is appened.
this.newRowIndex = -1;
AddNewRow(true /*createdByEditing*/);
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWCURRENTCELLDIRTYSTATECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnCursorChanged"]/*' />
protected override void OnCursorChanged(EventArgs e)
{
base.OnCursorChanged(e);
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_ignoreCursorChange])
{
this.oldCursor = this.Cursor;
}
}
internal void OnDataBindingComplete(ListChangedType listChangedType)
{
OnDataBindingComplete(new DataGridViewBindingCompleteEventArgs(listChangedType));
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnDataBindingComplete"]/*' />
protected virtual void OnDataBindingComplete(DataGridViewBindingCompleteEventArgs e)
{
DataGridViewBindingCompleteEventHandler eh = this.Events[EVENT_DATAGRIDVIEWDATABINDINGCOMPLETE] as DataGridViewBindingCompleteEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnDataError"]/*' />
[
SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions") // Not using options when RightToLeft == false
]
protected virtual void OnDataError(bool displayErrorDialogIfNoHandler, DataGridViewDataErrorEventArgs e)
{
DataGridViewDataErrorEventHandler eh = this.Events[EVENT_DATAGRIDVIEWDATAERROR] as DataGridViewDataErrorEventHandler;
if (!this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
if (eh == null)
{
if (displayErrorDialogIfNoHandler)
{
string errorText;
if (e.Exception == null)
{
errorText = SR.GetString(SR.DataGridView_ErrorMessageText_NoException);
}
else
{
errorText = SR.GetString(SR.DataGridView_ErrorMessageText_WithException, e.Exception);
}
if (this.RightToLeftInternal)
{
MessageBox.Show(errorText, SR.GetString(SR.DataGridView_ErrorMessageCaption), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
}
else
{
MessageBox.Show(errorText, SR.GetString(SR.DataGridView_ErrorMessageCaption), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
else
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
}
internal void OnDataErrorInternal(DataGridViewDataErrorEventArgs e)
{
OnDataError(!this.DesignMode /*displayErrorDialogIfNoHandler*/, e);
}
internal void OnDataGridViewElementStateChanged(DataGridViewElement element, int index, DataGridViewElementStates elementState)
{
DataGridViewColumn dataGridViewColumn = element as DataGridViewColumn;
if (dataGridViewColumn != null)
{
DataGridViewColumnStateChangedEventArgs dgvcsce = new DataGridViewColumnStateChangedEventArgs(dataGridViewColumn, elementState);
OnColumnStateChanged(dgvcsce);
}
else
{
DataGridViewRow dataGridViewRow = element as DataGridViewRow;
if (dataGridViewRow != null)
{
DataGridViewRowStateChangedEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWSTATECHANGED] as DataGridViewRowStateChangedEventHandler;
if (eh != null && dataGridViewRow.DataGridView != null && dataGridViewRow.Index == -1)
{
dataGridViewRow = this.Rows[index];
}
DataGridViewRowStateChangedEventArgs dgvrsce = new DataGridViewRowStateChangedEventArgs(dataGridViewRow, elementState);
OnRowStateChanged(dataGridViewRow.Index == -1 ? index : dataGridViewRow.Index, dgvrsce);
}
else
{
DataGridViewCell dataGridViewCell = element as DataGridViewCell;
if (dataGridViewCell != null)
{
DataGridViewCellStateChangedEventArgs dgvcsce = new DataGridViewCellStateChangedEventArgs(dataGridViewCell, elementState);
OnCellStateChanged(dgvcsce);
}
}
}
if ((elementState & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
{
if (this.noSelectionChangeCount > 0)
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_raiseSelectionChanged] = true;
}
else
{
OnSelectionChanged(EventArgs.Empty);
}
}
}
internal void OnDataGridViewElementStateChanging(DataGridViewElement element, int index, DataGridViewElementStates elementState)
{
DataGridViewColumn dataGridViewColumn = element as DataGridViewColumn;
if (dataGridViewColumn != null)
{
// column.Frozen | .Visible | .ReadOnly changing
switch (elementState)
{
case DataGridViewElementStates.Frozen:
case DataGridViewElementStates.Visible:
if (elementState == DataGridViewElementStates.Visible)
{
if (!dataGridViewColumn.Visible &&
dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.ColumnHeader &&
!this.ColumnHeadersVisible)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotMakeAutoSizedColumnVisible));
}
else if (!dataGridViewColumn.Visible &&
dataGridViewColumn.Frozen &&
dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
// alternative: throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotMakeAutoFillColumnVisible));
// DataGridView_CannotMakeAutoFillColumnVisible=The column cannot be made visible because its autosizing mode is Fill and it is frozen.
// Removing the Fill auto size mode when frozen column becomes visible (instead of throwing an exception)
dataGridViewColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
}
else if (dataGridViewColumn.Visible && this.ptCurrentCell.X == dataGridViewColumn.Index)
{
// Column of the current cell is made invisible. Trying to reset the current cell. May throw an exception.
ResetCurrentCell();
// Microsoft: Should the current cell be set to some cell after the operation?
}
}
if (elementState == DataGridViewElementStates.Frozen &&
!dataGridViewColumn.Frozen &&
dataGridViewColumn.Visible &&
dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
// Removing the Fill auto size mode when visible column becomes frozen (instead of throwing an exception)
dataGridViewColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
}
CorrectColumnFrozenStates(dataGridViewColumn, elementState == DataGridViewElementStates.Frozen);
break;
case DataGridViewElementStates.ReadOnly:
if (this.ptCurrentCell.X == dataGridViewColumn.Index &&
this.IsCurrentCellInEditMode &&
!dataGridViewColumn.ReadOnly &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange])
{
Debug.Assert(!this.ReadOnly);
// Column becomes read-only. Exit editing mode.
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit,
DataGridViewValidateCellInternal.Always /*validateCell*/,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
true /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell*/))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CommitFailedCannotCompleteOperation));
}
}
break;
default:
Debug.Fail("Unexpected DataGridViewElementStates param in DataGridView.OnDataGridViewElementStateChanging");
break;
}
}
else
{
DataGridViewRow dataGridViewRow = element as DataGridViewRow;
if (dataGridViewRow != null)
{
// row.Frozen | .Visible | .ReadOnly changing
int rowIndex = ((dataGridViewRow.Index > -1) ? dataGridViewRow.Index : index);
switch (elementState)
{
case DataGridViewElementStates.Frozen:
case DataGridViewElementStates.Visible:
if (elementState == DataGridViewElementStates.Visible && this.ptCurrentCell.Y == rowIndex)
{
Debug.Assert((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) != 0);
// Row of the current cell is made invisible.
if (this.DataSource != null)
{
Debug.Assert(this.dataConnection != null);
Debug.Assert(this.dataConnection.CurrencyManager != null);
Debug.Assert(this.dataConnection.CurrencyManager.Position == this.ptCurrentCell.Y);
// the row associated with the currency manager's position cannot be made invisble.
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CurrencyManagerRowCannotBeInvisible));
}
// Trying to reset the current cell. May throw an exception.
ResetCurrentCell();
// Microsoft: Should the current cell be set to some cell after the operation?
}
CorrectRowFrozenStates(dataGridViewRow, rowIndex, elementState == DataGridViewElementStates.Frozen);
break;
case DataGridViewElementStates.ReadOnly:
if (this.ptCurrentCell.Y == rowIndex &&
(this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.ReadOnly) == 0 &&
!this.ReadOnly &&
this.IsCurrentCellInEditMode &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange])
{
// Row becomes read-only. Exit editing mode.
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit,
DataGridViewValidateCellInternal.Always /*validateCell*/,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
true /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell*/))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CommitFailedCannotCompleteOperation));
}
}
break;
default:
Debug.Fail("Unexpected DataGridViewElementStates param in DataGridView.OnDataGridViewElementStateChanging");
break;
}
}
else
{
DataGridViewCell dataGridViewCell = element as DataGridViewCell;
if (dataGridViewCell != null)
{
// cell.ReadOnly changing
switch (elementState)
{
case DataGridViewElementStates.ReadOnly:
if (this.ptCurrentCell.X == dataGridViewCell.ColumnIndex &&
this.ptCurrentCell.Y == dataGridViewCell.RowIndex &&
this.IsCurrentCellInEditMode &&
!dataGridViewCell.ReadOnly &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange])
{
Debug.Assert(!this.Columns[dataGridViewCell.ColumnIndex].ReadOnly);
Debug.Assert(!this.Rows[dataGridViewCell.RowIndex].ReadOnly);
Debug.Assert(!this.ReadOnly);
// Current cell becomes read-only. Exit editing mode.
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit,
DataGridViewValidateCellInternal.Always /*validateCell*/,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
true /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell*/))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CommitFailedCannotCompleteOperation));
}
}
break;
default:
Debug.Fail("Unexpected DataGridViewElementStates param in DataGridView.OnDataGridViewElementStateChanging");
break;
}
}
else
{
Debug.Fail("Unexpected DataGridViewElement type in DataGridView.OnDataGridViewElementStateChanging");
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnDataMemberChanged"]/*' />
protected virtual void OnDataMemberChanged(EventArgs e)
{
RefreshColumnsAndRows();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWDATAMEMBERCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (this.dataConnection != null && this.dataConnection.CurrencyManager != null)
{
OnDataBindingComplete(ListChangedType.Reset);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnDataSourceChanged"]/*' />
protected virtual void OnDataSourceChanged(EventArgs e)
{
RefreshColumnsAndRows();
InvalidateRowHeights();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWDATASOURCECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (this.dataConnection != null && this.dataConnection.CurrencyManager != null)
{
OnDataBindingComplete(ListChangedType.Reset);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnDefaultCellStyleChanged"]/*' />
protected virtual void OnDefaultCellStyleChanged(EventArgs e)
{
DataGridViewCellStyleChangedEventArgs dgvcsce = e as DataGridViewCellStyleChangedEventArgs;
if (dgvcsce != null && !dgvcsce.ChangeAffectsPreferredSize)
{
Invalidate();
}
else
{
OnGlobalAutoSize();
if (this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWDEFAULTCELLSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnDefaultValuesNeeded"]/*' />
protected virtual void OnDefaultValuesNeeded(DataGridViewRowEventArgs e)
{
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWDEFAULTVALUESNEEDED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnDoubleClick"]/*' />
protected override void OnDoubleClick(EventArgs e)
{
base.OnDoubleClick(e);
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls] && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
MouseEventArgs me = e as MouseEventArgs;
if (me != null)
{
HitTestInfo hti = HitTest(me.X, me.Y);
if (hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar &&
me.Button == MouseButtons.Left)
{
OnCellDoubleClick(new DataGridViewCellEventArgs(hti.col, hti.row));
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnEditingControlShowing"]/*' />
protected virtual void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e)
{
DataGridViewEditingControlShowingEventHandler eh = this.Events[EVENT_DATAGRIDVIEWEDITINGCONTROLSHOWING] as DataGridViewEditingControlShowingEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnEditModeChanged"]/*' />
protected virtual void OnEditModeChanged(EventArgs e)
{
if (this.Focused &&
this.EditMode == DataGridViewEditMode.EditOnEnter &&
this.ptCurrentCell.X > -1 &&
!this.IsCurrentCellInEditMode)
{
// New edit mode is EditOnEnter and there is an editable current cell, try to go to edit mode.
BeginEditInternal(true /*selectAll*/);
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWEDITMODECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnEnabledChanged"]/*' />
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
if (GetAnyDisposingInHierarchy())
{
return;
}
if (this.IsHandleCreated && this.Enabled)
{
if (this.vertScrollBar != null && this.vertScrollBar.Visible)
{
int totalVisibleHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible);
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
this.vertScrollBar.Maximum = totalVisibleHeight - totalVisibleFrozenHeight;
this.vertScrollBar.Enabled = true;
}
if (this.horizScrollBar != null && this.horizScrollBar.Visible)
{
this.horizScrollBar.Enabled = true;
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnEnter"]/*' />
protected override void OnEnter(EventArgs e)
{
if (this.editingControl != null && this.editingControl.ContainsFocus)
{
return;
}
base.OnEnter(e);
// vsw 453314: there are cases when a control is on the designer and it still receives the OnEnter event.
// Guard against this.
if (this.DesignMode)
{
return;
}
this.dataGridViewState1[DATAGRIDVIEWSTATE1_leavingWithTabKey] = false;
if (this.ptCurrentCell.X > -1)
{
DataGridViewCell dataGridViewCell = null;
// We're re-entering a row we already entered earlier. The first time we entered the row,
// the DataGridView didn't have focus. This time it does. We don't want to recreate the new row a second time.
OnRowEnter(ref dataGridViewCell, this.ptCurrentCell.X, this.ptCurrentCell.Y, false /*canCreateNewRow*/, false /*validationFailureOccurred*/);
if (this.ptCurrentCell.X == -1)
{
return;
}
OnCellEnter(ref dataGridViewCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
// Force repainting of the current collumn's header cell to highlight it
if (this.SelectionMode == DataGridViewSelectionMode.FullRowSelect && AccessibilityImprovements.Level2)
{
InvalidateCellPrivate(this.ptCurrentCell.X, -1);
}
}
else if (!this.dataGridViewOper[DATAGRIDVIEWOPER_inMouseDown])
{
// Focus is given to the DataGridView control via a the TAB key.
MakeFirstDisplayedCellCurrentCell(true /*includeNewRow*/);
}
if (this.ptCurrentCell.X > -1 &&
!this.IsCurrentCellInEditMode)
{
if (this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null))
{
BeginEditInternal(true /*selectAll*/);
if (this.ptCurrentCell.X > -1 && this.CurrentCellInternal.EditType == null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inMouseDown])
{
// The current cell does not have an edit type so the data grid view did not put an edit control on top.
// We should invalidate the current cell so that the dataGridView repaints the focus around the current cell.
// But do that only if the dataGridView did not get the focus via mouse.
InvalidateCellPrivate(this.ptCurrentCell.X /*columnIndex*/, this.ptCurrentCell.Y /*rowIndex*/);
}
}
else if (!this.dataGridViewOper[DATAGRIDVIEWOPER_inMouseDown])
{
// When the focus is given to the DataGridView control via mouse
// the dataGridView changes selection so it invalidates the current cell anyway
//
// In any other case Invalidate the current cell so the dataGridView repaints the focus around the current cell
InvalidateCellPrivate(this.ptCurrentCell.X /*columnIndex*/, this.ptCurrentCell.Y /*rowIndex*/);
}
}
// Draw focus rectangle around the grid
if (this.IsGridFocusRectangleEnabled())
{
this.InvalidateRectangleEdges(this.GetGridFocusRectangle());
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnFontChanged"]/*' />
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
if (GetAnyDisposingInHierarchy ())
{
return;
}
// Change may be due to an ambient font change.
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientColumnHeadersFont] &&
this.ColumnHeadersDefaultCellStyle.Font != base.Font)
{
this.ColumnHeadersDefaultCellStyle.Font = base.Font;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientColumnHeadersFont] = true;
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = true;
OnColumnHeadersDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientRowHeadersFont] &&
this.RowHeadersDefaultCellStyle.Font != base.Font)
{
this.RowHeadersDefaultCellStyle.Font = base.Font;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientRowHeadersFont] = true;
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = true;
OnRowHeadersDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientFont] &&
this.DefaultCellStyle.Font != base.Font)
{
this.DefaultCellStyle.Font = base.Font;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientFont] = true;
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = true;
OnDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnForeColorChanged"]/*' />
protected override void OnForeColorChanged(EventArgs e)
{
base.OnForeColorChanged(e);
if (GetAnyDisposingInHierarchy())
{
return;
}
// Change may be due to an ambient forecolor change.
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientForeColor] && this.DefaultCellStyle.ForeColor != base.ForeColor)
{
this.DefaultCellStyle.ForeColor = base.ForeColor;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_ambientForeColor] = true;
this.CellStyleChangedEventArgs.ChangeAffectsPreferredSize = false;
OnDefaultCellStyleChanged(this.CellStyleChangedEventArgs);
}
}
private void OnGlobalAutoSize()
{
Invalidate();
if (this.noAutoSizeCount > 0)
{
return;
}
bool autoSizeRowHeaders = this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.EnableResizing &&
this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.DisableResizing;
if (autoSizeRowHeaders)
{
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode,
this.ColumnHeadersHeightSizeMode != DataGridViewColumnHeadersHeightSizeMode.AutoSize /*fixedColumnHeadersHeight*/,
this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None /*fixedRowsHeight*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, false /*fixedColumnsWidth*/);
}
if (this.autoSizeRowsMode != DataGridViewAutoSizeRowsMode.None)
{
AdjustShrinkingRows(this.autoSizeRowsMode, false /*fixedWidth*/, true /*internalAutosizing*/);
}
AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal.Header | DataGridViewAutoSizeColumnCriteriaInternal.AllRows | DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows, true /*fixedHeight*/);
if (autoSizeRowHeaders &&
(this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize || this.autoSizeRowsMode != DataGridViewAutoSizeRowsMode.None))
{
// Second round of row headers autosizing
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, true /*fixedRowsHeight*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
// Second round of column headers autosizing
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
if (this.autoSizeRowsMode != DataGridViewAutoSizeRowsMode.None)
{
// Second round of rows autosizing
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnGotFocus"]/*' />
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
if (this.ptCurrentCell.X != -1)
{
InvalidateCell(this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
// Inform Accessibility that our current cell contains the focus.
if (!this.dataGridViewOper[DATAGRIDVIEWOPER_inCurrentCellChange] &&
(!this.dataGridViewOper[DATAGRIDVIEWOPER_inEndEdit] || this.EditMode != DataGridViewEditMode.EditOnEnter) &&
(!this.dataGridViewOper[DATAGRIDVIEWOPER_inMouseDown] || this.EditMode != DataGridViewEditMode.EditOnEnter) &&
this.ptCurrentCell.X > -1)
{
// The name is misleading ( the current cell did not change ).
// However, AccessibilityNotifyCurrentCellChanged is now a public method so we can't change its name
// to better reflect its purpose.
AccessibilityNotifyCurrentCellChanged(this.ptCurrentCell);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnGridColorChanged"]/*' />
protected virtual void OnGridColorChanged(EventArgs e)
{
InvalidateInside();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWGRIDCOLORCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnHandleCreated"]/*' />
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (this.layout.dirty)
{
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
}
if (this.ptCurrentCell.X == -1)
{
MakeFirstDisplayedCellCurrentCell(false /*includeNewRow*/);
}
else
{
ScrollIntoView(this.ptCurrentCell.X, this.ptCurrentCell.Y, false /*forCurrentCellChange*/);
}
// do the AutoSize work that was skipped during initialization
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle])
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_autoSizedWithoutHandle] = false;
OnGlobalAutoSize();
}
SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(this.OnUserPreferenceChanged);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnHandleDestroyed"]/*' />
protected override void OnHandleDestroyed(EventArgs e)
{
SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(this.OnUserPreferenceChanged);
base.OnHandleDestroyed(e);
}
internal void OnInsertedColumn_PreNotification(DataGridViewColumn dataGridViewColumn)
{
// Fix the OldFirstDisplayedScrollingCol
this.displayedBandsInfo.CorrectColumnIndexAfterInsertion(dataGridViewColumn.Index, 1);
// Fix the Index of all following columns
CorrectColumnIndexesAfterInsertion(dataGridViewColumn, 1);
// Same effect as appending a column
OnAddedColumn(dataGridViewColumn);
}
internal void OnInsertedColumn_PostNotification(Point newCurrentCell)
{
// Update current cell if needed
if (newCurrentCell.X != -1)
{
Debug.Assert(this.ptCurrentCell.X == -1);
bool success = SetAndSelectCurrentCellAddress(newCurrentCell.X,
newCurrentCell.Y,
true,
false,
false,
false /*clearSelection*/,
this.Columns.GetColumnCount(DataGridViewElementStates.Visible) == 1 /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
}
internal void OnInsertedRow_PreNotification(int rowIndex, int insertionCount)
{
Debug.Assert(rowIndex >= 0);
Debug.Assert(insertionCount > 0);
// Fix the OldFirstDisplayedScrollingRow
this.displayedBandsInfo.CorrectRowIndexAfterInsertion(rowIndex, insertionCount);
// Fix the Index of all following rows
CorrectRowIndexesAfterInsertion(rowIndex, insertionCount);
// Next, same effect as adding a row
OnAddedRow_PreNotification(rowIndex);
}
internal void OnInsertedRow_PostNotification(int rowIndex, Point newCurrentCell, bool lastInsertion)
{
Debug.Assert(rowIndex >= 0);
// Same effect as adding a row
OnAddedRow_PostNotification(rowIndex);
// Update current cell if needed
if (lastInsertion && newCurrentCell.Y != -1)
{
Debug.Assert(this.ptCurrentCell.X == -1);
bool success = SetAndSelectCurrentCellAddress(newCurrentCell.X,
newCurrentCell.Y,
true,
false,
false,
false /*clearSelection*/,
this.Rows.GetRowCount(DataGridViewElementStates.Visible) == 1 /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
}
internal void OnInsertedRows_PreNotification(int rowIndex, DataGridViewRow[] dataGridViewRows)
{
Debug.Assert(rowIndex >= 0);
Debug.Assert(dataGridViewRows != null);
Debug.Assert(dataGridViewRows.Length > 0);
// Fix the OldFirstDisplayedScrollingRow
this.displayedBandsInfo.CorrectRowIndexAfterInsertion(rowIndex, dataGridViewRows.Length);
// Fix the Index of all following rows
CorrectRowIndexesAfterInsertion(rowIndex, dataGridViewRows.Length);
// Next, same effect as adding the rows
OnAddedRows_PreNotification(dataGridViewRows);
}
internal void OnInsertedRows_PostNotification(DataGridViewRow[] dataGridViewRows, Point newCurrentCell)
{
Debug.Assert(dataGridViewRows != null);
Debug.Assert(dataGridViewRows.Length > 0);
// Same effect as adding the rows
OnAddedRows_PostNotification(dataGridViewRows);
// Update current cell if needed
if (newCurrentCell.Y != -1)
{
Debug.Assert(this.ptCurrentCell.X == -1);
bool success = SetAndSelectCurrentCellAddress(newCurrentCell.X, newCurrentCell.Y, true, false, false, false /*clearSelection*/, false /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
}
internal void OnInsertingColumn(int columnIndexInserted, DataGridViewColumn dataGridViewColumn, out Point newCurrentCell)
{
Debug.Assert(dataGridViewColumn != null);
if (dataGridViewColumn.DataGridView != null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_ColumnAlreadyBelongsToDataGridView));
}
if (!this.InInitialization &&
dataGridViewColumn.SortMode == DataGridViewColumnSortMode.Automatic &&
(this.SelectionMode == DataGridViewSelectionMode.FullColumnSelect ||
this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridViewColumn_SortModeAndSelectionModeClash, DataGridViewColumnSortMode.Automatic.ToString(), this.SelectionMode.ToString()));
}
if (dataGridViewColumn.Visible)
{
// Note that dataGridViewColumn.DataGridView is set later on, so dataGridViewColumn.InheritedAutoSizeMode should not be used
// Make sure the column does not autosize based only on header while column headers are invisible
if (!this.ColumnHeadersVisible &&
(dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.ColumnHeader || (dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.NotSet && this.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.ColumnHeader)))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddAutoSizedColumn));
}
// Make sure the column is not frozen and auto fills
if (dataGridViewColumn.Frozen &&
(dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.Fill || (dataGridViewColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.NotSet && this.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.Fill)))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddAutoFillColumn));
}
}
// check for correctness of frozen state - throws exception if state is incorrect.
CorrectColumnFrozenState(dataGridViewColumn, columnIndexInserted);
// Reset current cell if there is one, no matter the relative position of the columns involved
if (this.ptCurrentCell.X != -1)
{
newCurrentCell = new Point(columnIndexInserted <= this.ptCurrentCell.X ? this.ptCurrentCell.X + 1 : this.ptCurrentCell.X,
this.ptCurrentCell.Y);
ResetCurrentCell();
}
else
{
newCurrentCell = new Point(-1, -1);
}
// prepare the existing rows by inserting cells of correct type
if (this.Rows.Count > 0)
{
// Only require a default cell type when there are rows to fill
if (dataGridViewColumn.CellType == null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAddUntypedColumn));
}
if (dataGridViewColumn.CellTemplate.DefaultNewRowValue != null && this.newRowIndex != -1)
{
// New row needs to be unshared before addition of new cell with a Value != null
DataGridViewRow newRow = this.Rows[this.newRowIndex];
}
int newColumnCount = this.Columns.Count + 1;
try
{
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Cells.Count < newColumnCount)
{
DataGridViewCell dataGridViewCellNew = (DataGridViewCell)dataGridViewColumn.CellTemplate.Clone();
dataGridViewRow.Cells.InsertInternal(columnIndexInserted, dataGridViewCellNew);
if (rowIndex == this.newRowIndex)
{
dataGridViewCellNew.Value = dataGridViewCellNew.DefaultNewRowValue;
}
dataGridViewCellNew.DataGridViewInternal = this;
dataGridViewCellNew.OwningRowInternal = dataGridViewRow;
dataGridViewCellNew.OwningColumnInternal = dataGridViewColumn;
}
}
}
catch
{
// An error occurred while inserting the cells. Revert all the insertions.
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Cells.Count == newColumnCount)
{
dataGridViewRow.Cells.RemoveAtInternal(columnIndexInserted);
}
else
{
Debug.Assert(dataGridViewRow.Cells.Count < newColumnCount);
break;
}
}
throw;
}
}
// Update the indexes of selected columns to compensate for the insertion of this column
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
int columnEntries = this.selectedBandIndexes.Count;
int columnEntry = 0;
while (columnEntry < columnEntries)
{
int columnIndex = this.selectedBandIndexes[columnEntry];
if (columnIndexInserted <= columnIndex)
{
this.selectedBandIndexes[columnEntry] = columnIndex + 1;
}
columnEntry++;
}
if (this.selectedBandSnapshotIndexes != null)
{
columnEntries = this.selectedBandSnapshotIndexes.Count;
columnEntry = 0;
while (columnEntry < columnEntries)
{
int columnIndex = this.selectedBandSnapshotIndexes[columnEntry];
if (columnIndexInserted <= columnIndex)
{
this.selectedBandSnapshotIndexes[columnEntry] = columnIndex + 1;
}
columnEntry++;
}
}
break;
}
}
internal void OnInsertingRow(int rowIndexInserted,
DataGridViewRow dataGridViewRow,
DataGridViewElementStates rowState,
ref Point newCurrentCell,
bool firstInsertion,
int insertionCount,
bool force)
{
// Reset the current cell's address if it's after the inserted row.
if (firstInsertion)
{
if (this.ptCurrentCell.Y != -1 && rowIndexInserted <= this.ptCurrentCell.Y)
{
newCurrentCell = new Point(this.ptCurrentCell.X, this.ptCurrentCell.Y + insertionCount);
if (force)
{
// When force is true, the underlying data was already added, therefore we need to avoid accessing any back-end data
// since we might be off by 1 row.
this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell] = true;
bool success = SetCurrentCellAddressCore(-1, -1, true /*setAnchorCellAddress*/, false /*validateCurrentCell*/, false);
Debug.Assert(success);
}
else
{
ResetCurrentCell();
}
}
else
{
newCurrentCell = new Point(-1, -1);
}
}
else
{
if (newCurrentCell.Y != -1)
{
newCurrentCell.Y += insertionCount;
}
}
// For now same checks as for OnAddingRow
OnAddingRow(dataGridViewRow, rowState, false /*checkFrozenState*/);
// check for correctness of frozen state - throws exception if state is incorrect.
CorrectRowFrozenState(dataGridViewRow, rowState, rowIndexInserted);
// Update the indexes of selected rows to compensate for the insertion of this row
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
int rowEntries = this.selectedBandIndexes.Count;
int rowEntry = 0;
while (rowEntry < rowEntries)
{
int rowIndex = this.selectedBandIndexes[rowEntry];
if (rowIndexInserted <= rowIndex)
{
this.selectedBandIndexes[rowEntry] = rowIndex + insertionCount;
}
rowEntry++;
}
if (this.selectedBandSnapshotIndexes != null)
{
rowEntries = this.selectedBandSnapshotIndexes.Count;
rowEntry = 0;
while (rowEntry < rowEntries)
{
int rowIndex = this.selectedBandSnapshotIndexes[rowEntry];
if (rowIndexInserted <= rowIndex)
{
this.selectedBandSnapshotIndexes[rowEntry] = rowIndex + insertionCount;
}
rowEntry++;
}
}
break;
}
}
internal void OnInsertingRows(int rowIndexInserted, DataGridViewRow[] dataGridViewRows, ref Point newCurrentCell)
{
Debug.Assert(dataGridViewRows != null);
// Reset the current cell's address if it's after the inserted row.
if (this.ptCurrentCell.Y != -1 && rowIndexInserted <= this.ptCurrentCell.Y)
{
newCurrentCell = new Point(this.ptCurrentCell.X, this.ptCurrentCell.Y + dataGridViewRows.Length);
ResetCurrentCell();
}
else
{
newCurrentCell = new Point(-1, -1);
}
// For now almost same checks as for OnAddingRows
// OnAddingRows checks for Selected status of rows.
OnAddingRows(dataGridViewRows, false /*checkFrozenStates*/);
// Check for Frozen state correctness
CorrectRowFrozenStates(dataGridViewRows, rowIndexInserted);
// Update the indexes of selected rows to compensate for the insertion of this row
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
int rowEntries = this.selectedBandIndexes.Count;
int rowEntry = 0;
while (rowEntry < rowEntries)
{
int rowIndex = this.selectedBandIndexes[rowEntry];
if (rowIndexInserted <= rowIndex)
{
this.selectedBandIndexes[rowEntry] = rowIndex + dataGridViewRows.Length;
}
rowEntry++;
}
if (this.selectedBandSnapshotIndexes != null)
{
rowEntries = this.selectedBandSnapshotIndexes.Count;
rowEntry = 0;
while (rowEntry < rowEntries)
{
int rowIndex = this.selectedBandSnapshotIndexes[rowEntry];
if (rowIndexInserted <= rowIndex)
{
this.selectedBandSnapshotIndexes[rowEntry] = rowIndex + dataGridViewRows.Length;
}
rowEntry++;
}
}
break;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnKeyDown"]/*' />
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Handled)
{
return;
}
// Forward key down to current cell if any
if (this.ptCurrentCell.X != -1)
{
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCell != null);
if (dataGridViewCell.KeyDownUnsharesRowInternal(e, this.ptCurrentCell.Y))
{
DataGridViewRow dataGridViewRow = this.Rows[this.ptCurrentCell.Y];
this.CurrentCellInternal.OnKeyDownInternal(e, this.ptCurrentCell.Y);
}
else
{
dataGridViewCell.OnKeyDownInternal(e, this.ptCurrentCell.Y);
}
}
if (!e.Handled)
{
switch (e.KeyData & Keys.KeyCode)
{
case Keys.A:
case Keys.C:
case Keys.D0:
case Keys.NumPad0:
case Keys.Delete:
case Keys.Down:
case Keys.F2:
case Keys.F3:
case Keys.End:
case Keys.Enter:
case Keys.Escape:
case Keys.Home:
case Keys.Insert:
case Keys.Left:
case Keys.Next:
case Keys.Prior:
case Keys.Right:
case Keys.Space:
case Keys.Tab:
case Keys.Up:
{
e.Handled = ProcessDataGridViewKey(e);
break;
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnKeyPress"]/*' />
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
if (e.Handled)
{
return;
}
// Forward key press to current cell if any
if (this.ptCurrentCell.X != -1)
{
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCell != null);
if (dataGridViewCell.KeyPressUnsharesRowInternal(e, this.ptCurrentCell.Y))
{
DataGridViewRow dataGridViewRow = this.Rows[this.ptCurrentCell.Y];
this.CurrentCellInternal.OnKeyPressInternal(e, this.ptCurrentCell.Y);
}
else
{
dataGridViewCell.OnKeyPressInternal(e, this.ptCurrentCell.Y);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnKeyUp"]/*' />
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
if (e.Handled)
{
return;
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackKeyboardColResize] && (e.KeyData & Keys.Alt) != Keys.Alt && AccessibilityImprovements.Level2)
{
this.EndColumnResize(this.currentColSplitBar);
this.ResetKeyboardTrackingState();
return;
}
// Forward key up to current cell if any
if (this.ptCurrentCell.X != -1)
{
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCell != null);
if (dataGridViewCell.KeyUpUnsharesRowInternal(e, this.ptCurrentCell.Y))
{
DataGridViewRow dataGridViewRow = this.Rows[this.ptCurrentCell.Y];
this.CurrentCellInternal.OnKeyUpInternal(e, this.ptCurrentCell.Y);
}
else
{
dataGridViewCell.OnKeyUpInternal(e, this.ptCurrentCell.Y);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnLayout"]/*' />
protected override void OnLayout(LayoutEventArgs e)
{
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlChanging])
{
return;
}
base.OnLayout(e);
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
if (this.RightToLeftInternal)
{
Invalidate();
}
if (this.editingControl != null)
{
PositionEditingControl(true, true, false);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnLeave"]/*' />
protected override void OnLeave(EventArgs e)
{
if (this.ptCurrentCell.X > -1 && !this.dataGridViewState1[DATAGRIDVIEWSTATE1_leavingWithTabKey])
{
DataGridViewCell dataGridViewCell = null;
OnCellLeave(ref dataGridViewCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
if (this.ptCurrentCell.X == -1)
{
return;
}
OnRowLeave(ref dataGridViewCell, this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
if (!this.dataGridViewState1[DATAGRIDVIEWSTATE1_leavingWithTabKey])
{
base.OnLeave(e);
// 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*/);
}
}
// Erase focus rectangle around the grid
if (this.IsGridFocusRectangleEnabled())
{
this.InvalidateRectangleEdges(this.GetGridFocusRectangle());
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnLostFocus"]/*' />
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
if (this.ptCurrentCell.X != -1)
{
InvalidateCell(this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseClick"]/*' />
protected override void OnMouseClick(MouseEventArgs e)
{
bool mouseClickRaised = false;
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize])
{
HitTestInfo hti = HitTest(e.X, e.Y);
if (this.ptMouseDownCell.X == hti.col &&
this.ptMouseDownCell.Y == hti.row &&
(e.Button != MouseButtons.Left ||
this.ptMouseDownCell.X == -1 ||
this.ptMouseDownCell.Y == -1 ||
(this.ptMouseDownCell.X == this.ptCurrentCell.X &&
this.ptMouseDownCell.Y == this.ptCurrentCell.Y)))
{
DataGridViewCellMouseEventArgs dgvcme = null;
if (hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar)
{
int mouseX = e.X - hti.ColumnX;
if (this.RightToLeftInternal)
{
mouseX += ((hti.col == -1) ? this.RowHeadersWidth : this.Columns[hti.col].Thickness);
}
dgvcme = new DataGridViewCellMouseEventArgs(hti.col, hti.row, mouseX, e.Y - hti.RowY, e);
RecordCellMouseClick(dgvcme);
if (e.Button == MouseButtons.Left)
{
OnCellClick(new DataGridViewCellEventArgs(hti.col, hti.row));
}
base.OnMouseClick(e);
mouseClickRaised = true;
if (dgvcme.ColumnIndex < this.Columns.Count && dgvcme.RowIndex < this.Rows.Count)
{
OnCellMouseClick(dgvcme);
}
}
else
{
base.OnMouseClick(e);
mouseClickRaised = true;
}
if (!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation])
{
switch (hti.typeInternal)
{
case DataGridViewHitTestTypeInternal.ColumnHeader:
case DataGridViewHitTestTypeInternal.ColumnHeaderLeft:
case DataGridViewHitTestTypeInternal.ColumnHeaderRight:
case DataGridViewHitTestTypeInternal.FirstColumnHeaderLeft:
{
Debug.Assert(dgvcme != null);
if (dgvcme.ColumnIndex < this.Columns.Count && dgvcme.RowIndex < this.Rows.Count)
{
OnColumnHeaderMouseClick(dgvcme);
}
break;
}
case DataGridViewHitTestTypeInternal.RowHeader:
{
Debug.Assert(dgvcme != null);
if (dgvcme.ColumnIndex < this.Columns.Count && dgvcme.RowIndex < this.Rows.Count)
{
OnRowHeaderMouseClick(dgvcme);
}
break;
}
}
}
}
}
if (!mouseClickRaised)
{
base.OnMouseClick(e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseDoubleClick"]/*' />
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize])
{
HitTestInfo hti = HitTest(e.X, e.Y);
if (this.ptMouseDownCell.X == hti.col && this.ptMouseDownCell.Y == hti.row)
{
DataGridViewCellMouseEventArgs dgvcme = null;
if (hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar)
{
int mouseX = e.X - hti.ColumnX;
if (this.RightToLeftInternal)
{
mouseX += ((hti.col == -1) ? this.RowHeadersWidth : this.Columns[hti.col].Thickness);
}
dgvcme = new DataGridViewCellMouseEventArgs(hti.col, hti.row, mouseX, e.Y - hti.RowY, e);
OnCellMouseDoubleClick(dgvcme);
}
if (!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation])
{
switch (hti.typeInternal)
{
case DataGridViewHitTestTypeInternal.ColumnHeader:
case DataGridViewHitTestTypeInternal.ColumnHeaderLeft:
case DataGridViewHitTestTypeInternal.ColumnHeaderRight:
case DataGridViewHitTestTypeInternal.FirstColumnHeaderLeft:
{
Debug.Assert(dgvcme != null);
if (dgvcme.ColumnIndex < this.Columns.Count && dgvcme.RowIndex < this.Rows.Count)
{
OnColumnHeaderMouseDoubleClick(dgvcme);
}
break;
}
case DataGridViewHitTestTypeInternal.ColumnResizeLeft:
case DataGridViewHitTestTypeInternal.ColumnResizeRight:
{
int columnIndex = (hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeRight) ? hti.col : hti.adjacentCol;
if (columnIndex < this.Columns.Count)
{
HandledMouseEventArgs hme = new HandledMouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta, false /*defaultHandledValue*/);
DataGridViewColumnDividerDoubleClickEventArgs dgvcddce = new DataGridViewColumnDividerDoubleClickEventArgs(columnIndex, hme);
Debug.Assert(this.Columns[columnIndex].Resizable == DataGridViewTriState.True);
OnColumnDividerDoubleClick(dgvcddce);
}
break;
}
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeTop:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeBottom:
case DataGridViewHitTestTypeInternal.ColumnHeadersResizeTop:
case DataGridViewHitTestTypeInternal.ColumnHeadersResizeBottom:
{
HandledMouseEventArgs hme = new HandledMouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta, false /*defaultHandledValue*/);
DataGridViewRowDividerDoubleClickEventArgs dgvrddce = new DataGridViewRowDividerDoubleClickEventArgs(-1, hme);
Debug.Assert(this.columnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.EnableResizing);
OnRowDividerDoubleClick(dgvrddce);
break;
}
case DataGridViewHitTestTypeInternal.RowHeader:
{
Debug.Assert(dgvcme != null);
if (dgvcme.ColumnIndex < this.Columns.Count && dgvcme.RowIndex < this.Rows.Count)
{
OnRowHeaderMouseDoubleClick(dgvcme);
}
break;
}
case DataGridViewHitTestTypeInternal.RowResizeBottom:
case DataGridViewHitTestTypeInternal.RowResizeTop:
{
int rowIndex = (hti.typeInternal == DataGridViewHitTestTypeInternal.RowResizeBottom) ? hti.row : hti.adjacentRow;
if (rowIndex < this.Rows.Count)
{
HandledMouseEventArgs hme = new HandledMouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta, false /*defaultHandledValue*/);
DataGridViewRowDividerDoubleClickEventArgs dgvrddce = new DataGridViewRowDividerDoubleClickEventArgs(rowIndex, hme);
Debug.Assert(this.Rows[rowIndex].Resizable == DataGridViewTriState.True);
OnRowDividerDoubleClick(dgvrddce);
}
break;
}
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeLeft:
case DataGridViewHitTestTypeInternal.TopLeftHeaderResizeRight:
case DataGridViewHitTestTypeInternal.RowHeadersResizeLeft:
case DataGridViewHitTestTypeInternal.RowHeadersResizeRight:
{
HandledMouseEventArgs hme = new HandledMouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta, false /*defaultHandledValue*/);
DataGridViewColumnDividerDoubleClickEventArgs dgvcddce = new DataGridViewColumnDividerDoubleClickEventArgs(-1, hme);
Debug.Assert(this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing);
OnColumnDividerDoubleClick(dgvcddce);
break;
}
}
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseDown"]/*' />
protected override void OnMouseDown(MouseEventArgs e)
{
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves] = true;
}
base.OnMouseDown(e);
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls])
{
return;
}
if (this.ptMouseDownCell.X != -2)
{
// Happens when user pushes the mouse wheel down while the left mouse button is already down
Debug.Assert(this.ptMouseDownCell.Y != -2);
return;
}
HitTestInfo hti = HitTest(e.X, e.Y);
if (hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar)
{
this.ptMouseDownCell.X = hti.col;
this.ptMouseDownCell.Y = hti.row;
this.ptMouseDownGridCoord = new Point(e.X, e.Y);
int mouseX = e.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, e.Y - hti.RowY, e);
OnCellMouseDown(dgvcme);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseEnter"]/*' />
protected override void OnMouseEnter(EventArgs e)
{
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseOverRemovedEditingCtrl] &&
!this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseOverRemovedEditingPanel] &&
this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseEnterExpected] &&
!this.toolTipControl.Activated)
{
base.OnMouseEnter(e);
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseOverRemovedEditingCtrl] = false;
this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseOverRemovedEditingPanel] = false;
this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseEnterExpected] = false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseLeave"]/*' />
protected override void OnMouseLeave(EventArgs e)
{
// when the mouse leaves the dataGridView control, reset the cursor to the previously cached one
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet] = false;
this.CursorInternal = this.oldCursor;
}
bool mouseOverEditingControl = this.MouseOverEditingControl;
bool mouseOverEditingPanel = this.MouseOverEditingPanel;
bool mouseOverToolTipControl = this.toolTipControl.Activated && this.ClientRectangle.Contains(PointToClient(Control.MousePosition));
if (!mouseOverEditingPanel && !mouseOverEditingControl && !mouseOverToolTipControl && this.ptMouseEnteredCell.X != -2)
{
if (this.ptMouseEnteredCell.X >= -1 && this.ptMouseEnteredCell.X < this.Columns.Count &&
this.ptMouseEnteredCell.Y >= -1 && this.ptMouseEnteredCell.Y < this.Rows.Count)
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(this.ptMouseEnteredCell.X, this.ptMouseEnteredCell.Y);
OnCellMouseLeave(dgvce);
}
else
{
this.ptMouseEnteredCell.X = this.ptMouseEnteredCell.Y = -2;
}
}
ResetTrackingState();
this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves] = false;
if (!mouseOverEditingPanel && !mouseOverEditingControl && !mouseOverToolTipControl && !this.MouseOverScrollBar)
{
this.toolTipControl.Activate(false /*activate*/);
base.OnMouseLeave(e);
this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseEnterExpected] = true;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseMove"]/*' />
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
HitTestInfo hti = HitTest(e.X, e.Y);
UpdateMouseEnteredCell(hti, e);
// We need to give UI feedback when the user is resizing a column
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColResize])
{
MoveRowHeadersOrColumnResize(e.X);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowResize])
{
MoveColumnHeadersOrRowResize(e);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation])
{
MoveColumnRelocation(e, hti);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize])
{
MoveColumnHeadersOrRowResize(e);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize])
{
MoveRowHeadersOrColumnResize(e.X);
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColResize] ||
this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize] ||
((hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.TopLeftHeaderResizeLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.TopLeftHeaderResizeRight ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeRight ||
hti.typeInternal == DataGridViewHitTestTypeInternal.RowHeadersResizeLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.RowHeadersResizeRight) &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect]))
{
if (!this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet] = true;
this.oldCursor = this.Cursor;
}
this.CursorInternal = Cursors.SizeWE;
return;
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowResize] ||
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize] ||
((hti.typeInternal == DataGridViewHitTestTypeInternal.RowResizeBottom ||
hti.typeInternal == DataGridViewHitTestTypeInternal.TopLeftHeaderResizeTop ||
hti.typeInternal == DataGridViewHitTestTypeInternal.TopLeftHeaderResizeBottom ||
hti.typeInternal == DataGridViewHitTestTypeInternal.RowResizeTop ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeadersResizeTop ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeadersResizeBottom) &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect]))
{
if (!this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet] = true;
this.oldCursor = this.Cursor;
}
this.CursorInternal = Cursors.SizeNS;
return;
}
/* Whidbey bug 156884 - no longer show hand cursor
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation] &&
(hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnResizeRight ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeaderLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.ColumnHeaderRight ||
hti.typeInternal == DataGridViewHitTestTypeInternal.FirstColumnHeaderLeft ||
hti.typeInternal == DataGridViewHitTestTypeInternal.TopLeftHeaderResizeRight))
{
if (!this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet] = true;
this.oldCursor = this.Cursor;
}
this.CursorInternal = Cursors.Hand;
return;
}*/
else if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_customCursorSet] = false;
this.CursorInternal = this.oldCursor;
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] ||
this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] ||
this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect])
{
int xOffset, yOffset, mouseX = e.X, mouseY = e.Y;
if (GetOutOfBoundCorrectedHitTestInfo(ref hti, ref mouseX, ref mouseY, out xOffset, out yOffset))
{
if (xOffset == 0)
{
if (this.horizScrollTimer != null && this.horizScrollTimer.Enabled)
{
// Mouse's X came in-bound - need to stop the horizontal scroll timer
this.horizScrollTimer.Enabled = false;
}
}
else if (this.horizScrollTimer == null || !this.horizScrollTimer.Enabled)
{
// Need to start delayed horizontal scroll
this.HorizScrollTimer.Interval = GetColumnScrollRate(Math.Abs(xOffset));
this.HorizScrollTimer.Enabled = true;
}
if (yOffset == 0)
{
if (this.vertScrollTimer != null && this.vertScrollTimer.Enabled)
{
// Mouse's Y came in-bound - need to stop the vertical scroll timer
this.vertScrollTimer.Enabled = false;
}
}
else if (this.vertScrollTimer == null || !this.vertScrollTimer.Enabled)
{
// Need to start delayed vertical scroll
this.VertScrollTimer.Interval = GetRowScrollRate(Math.Abs(yOffset));
this.VertScrollTimer.Enabled = true;
}
if (this.HorizScrollTimer.Enabled || this.VertScrollTimer.Enabled)
{
return;
}
if (/*!this.dataGridViewState1[DATAGRIDVIEWSTATE1_scrolledSinceMouseDown] && */
hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar)
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] && hti.col >= 0)
{
OnColumnSelectMouseMove(hti);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] && hti.row >= 0)
{
OnRowSelectMouseMove(hti);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect] && hti.col >= 0 && hti.row >= 0)
{
OnCellSelectMouseMove(hti);
}
}
}
}
#if DEBUG
else
{
Debug.Assert(this.vertScrollTimer == null || !this.vertScrollTimer.Enabled);
Debug.Assert(this.horizScrollTimer == null || !this.horizScrollTimer.Enabled);
}
#endif
if (!this.toolTipControl.Activated)
{
//
// After processing the MouseMove event, the tool tip is still not activated.
// Reset the tool tip cell.
this.ptToolTipCell = new Point(-1, -1);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseUp"]/*' />
protected override void OnMouseUp(MouseEventArgs e)
{
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_messageFromEditingCtrls])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_scrolledSinceMouseDown] = false;
HitTestInfo hti = HitTest(e.X, e.Y);
if (!this.IsMouseOperationActive())
{
if (hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar)
{
int mouseX = e.X - hti.ColumnX;
if (this.RightToLeftInternal)
{
mouseX += ((hti.col == -1) ? this.RowHeadersWidth : this.Columns[hti.col].Thickness);
}
DataGridViewCellMouseEventArgs dgvcme;
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_nextMouseUpIsDouble])
{
MouseEventArgs meTmp = new MouseEventArgs(e.Button, 2, e.X, e.Y, e.Delta);
dgvcme = new DataGridViewCellMouseEventArgs(hti.col, hti.row, mouseX, e.Y - hti.RowY, meTmp);
}
else
{
dgvcme = new DataGridViewCellMouseEventArgs(hti.col, hti.row, mouseX, e.Y - hti.RowY, e);
}
if (hti.col >= 0 && this.ptMouseDownCell.X == hti.col &&
hti.row >= 0 && this.ptMouseDownCell.Y == hti.row &&
this.EditMode == DataGridViewEditMode.EditOnEnter &&
this.editingControl != null)
{
OnClick(e);
OnMouseClick(e);
}
CorrectFocus(true /*onlyIfGridHasFocus*/);
if (dgvcme.ColumnIndex < this.Columns.Count && dgvcme.RowIndex < this.Rows.Count)
{
OnCellMouseUp(dgvcme);
}
}
else if (hti.Type == DataGridViewHitTestType.None)
{
// VS Whidbey bug 469429
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
else
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColResize])
{
EndColumnResize(e);
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowResize])
{
EndRowResize(e);
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColRelocation])
{
EndColumnRelocation(e, hti);
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize])
{
EndColumnHeadersResize(e);
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize])
{
EndRowHeadersResize(e);
}
// VS Whidbey bug 256893
CorrectFocus(true /*onlyIfGridHasFocus*/);
// Updating the hit test info since the EndXXX operation above may have invalidated the previously
// determined hti.
hti = HitTest(e.X, e.Y);
if (hti.Type != DataGridViewHitTestType.None &&
hti.Type != DataGridViewHitTestType.HorizontalScrollBar &&
hti.Type != DataGridViewHitTestType.VerticalScrollBar)
{
int mouseX = e.X - hti.ColumnX;
if (this.RightToLeftInternal)
{
mouseX += ((hti.col == -1) ? this.RowHeadersWidth : this.Columns[hti.col].Thickness);
}
OnCellMouseUp(new DataGridViewCellMouseEventArgs(hti.col, hti.row, mouseX, e.Y - hti.RowY, e));
}
}
ResetTrackingState();
}
base.OnMouseUp(e);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMouseWheel"]/*' />
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
HandledMouseEventArgs hme = e as HandledMouseEventArgs;
if (hme != null && hme.Handled)
{
// The application event handler handled the scrolling - don't do anything more.
return;
}
if ((ModifierKeys & (Keys.Shift | Keys.Alt)) != 0 || MouseButtons != MouseButtons.None)
{
return; // Do not scroll when Shift or Alt key is down, or when a mouse button is down.
}
bool verticalScroll = ((ModifierKeys & Keys.Control) == 0);
ScrollBar sb = (verticalScroll ? (ScrollBar) this.vertScrollBar : (ScrollBar) this.horizScrollBar);
if (!sb.Visible || !sb.Enabled)
{
return; // Do not scroll when the corresponding scrollbar is invisible or disabled
}
if (hme != null)
{
hme.Handled = true;
}
int wheelScrollLines = SystemInformation.MouseWheelScrollLines;
if (wheelScrollLines == 0)
{
return; // Do not scroll when the user system setting is 0 lines per notch
}
Debug.Assert(this.cumulativeVerticalWheelDelta > -NativeMethods.WHEEL_DELTA);
Debug.Assert(this.cumulativeVerticalWheelDelta < NativeMethods.WHEEL_DELTA);
Debug.Assert(this.cumulativeHorizontalWheelDelta > -NativeMethods.WHEEL_DELTA);
Debug.Assert(this.cumulativeHorizontalWheelDelta < NativeMethods.WHEEL_DELTA);
float partialNotches;
if (verticalScroll)
{
this.cumulativeVerticalWheelDelta += e.Delta;
partialNotches = (float) this.cumulativeVerticalWheelDelta / (float) NativeMethods.WHEEL_DELTA;
}
else
{
this.cumulativeHorizontalWheelDelta += e.Delta;
partialNotches = (float) this.cumulativeHorizontalWheelDelta / (float) NativeMethods.WHEEL_DELTA;
}
int fullNotches = (int) partialNotches;
if (wheelScrollLines == -1)
{
// Equivalent to large change scrolls
if (fullNotches != 0)
{
if (this.ptCurrentCell.X >= 0 &&
!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
false /*forCurrentCellChange*/, false /*forCurrentRowChange*/))
{
// Could not commit edited cell value
return;
}
if (verticalScroll)
{
int originalVerticalOffset = this.VerticalOffset;
this.VerticalOffset -= fullNotches * this.vertScrollBar.LargeChange;
if (Math.Abs(this.VerticalOffset - originalVerticalOffset) >= Math.Abs(fullNotches * this.vertScrollBar.LargeChange))
{
this.cumulativeVerticalWheelDelta -= fullNotches * NativeMethods.WHEEL_DELTA;
}
else
{
this.cumulativeVerticalWheelDelta = 0;
}
}
else
{
int originalHorizontalOffset = this.HorizontalOffset;
this.HorizontalOffset -= fullNotches * this.horizScrollBar.LargeChange;
if (Math.Abs(this.HorizontalOffset - originalHorizontalOffset) >= Math.Abs(fullNotches * this.horizScrollBar.LargeChange))
{
this.cumulativeHorizontalWheelDelta -= fullNotches * NativeMethods.WHEEL_DELTA;
}
else
{
this.cumulativeHorizontalWheelDelta = 0;
}
}
}
}
else
{
// Evaluate number of bands to scroll
int scrollBands = (int) ((float) wheelScrollLines * partialNotches);
if (scrollBands != 0)
{
if (this.ptCurrentCell.X >= 0 &&
!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
false /*forCurrentCellChange*/, false /*forCurrentRowChange*/))
{
// Could not commit edited cell value
return;
}
int absScrollBands;
if (verticalScroll)
{
if (scrollBands > 0)
{
absScrollBands = scrollBands;
while (this.vertScrollBar.Value != this.vertScrollBar.Minimum && absScrollBands > 0)
{
ScrollRowsByCount(-1, ScrollEventType.SmallDecrement);
absScrollBands--;
}
if (this.vertScrollBar.Value == this.vertScrollBar.Minimum)
{
this.cumulativeVerticalWheelDelta = 0;
}
else
{
this.cumulativeVerticalWheelDelta -= (int) ((float) scrollBands * ((float) NativeMethods.WHEEL_DELTA / (float) wheelScrollLines));
}
}
else
{
absScrollBands = -scrollBands;
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (absScrollBands > 0 &&
this.vertScrollBar.Value + this.Rows.SharedRow(this.displayedBandsInfo.FirstDisplayedScrollingRow).GetHeight(this.displayedBandsInfo.FirstDisplayedScrollingRow) <=
this.vertScrollBar.Maximum - ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight))
{
ScrollRowsByCount(1, ScrollEventType.SmallIncrement);
// Assuming totalVisibleFrozenHeight is unchanged by scrolling operation
Debug.Assert(totalVisibleFrozenHeight == this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen));
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
absScrollBands--;
}
if (this.vertScrollBar.Value + this.Rows.SharedRow(this.displayedBandsInfo.FirstDisplayedScrollingRow).GetHeight(this.displayedBandsInfo.FirstDisplayedScrollingRow) >
this.vertScrollBar.Maximum - ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight))
{
this.cumulativeVerticalWheelDelta = 0;
}
else
{
this.cumulativeVerticalWheelDelta -= (int) ((float) scrollBands * ((float) NativeMethods.WHEEL_DELTA / (float) wheelScrollLines));
}
}
}
else
{
int extremeScrollBarValue, scrollBand;
if (scrollBands > 0)
{
extremeScrollBarValue = this.horizScrollBar.Minimum;
scrollBand = -1;
}
else
{
extremeScrollBarValue = this.horizScrollBar.Maximum;
scrollBand = 1;
}
absScrollBands = Math.Abs(scrollBands);
while (this.horizScrollBar.Value != extremeScrollBarValue && absScrollBands > 0)
{
ScrollColumns(scrollBand);
absScrollBands--;
}
if (this.horizScrollBar.Value == extremeScrollBarValue)
{
this.cumulativeHorizontalWheelDelta = 0;
}
else
{
this.cumulativeHorizontalWheelDelta -= (int) ((float) scrollBands * ((float) NativeMethods.WHEEL_DELTA / (float) wheelScrollLines));
}
}
}
}
}
internal void OnMouseWheelInternal(MouseEventArgs e)
{
// Notification forwarded from editing control
OnMouseWheel(e);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnMultiSelectChanged"]/*' />
protected virtual void OnMultiSelectChanged(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWMULTISELECTCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnNewRowNeeded"]/*' />
protected virtual void OnNewRowNeeded(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWNEWROWNEEDED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnPaint"]/*' />
protected override void OnPaint(PaintEventArgs e)
{
try
{
// We can't paint if we are disposed.
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] || this.IsDisposed)
{
return;
}
if (this.layout.dirty)
{
PerformLayoutPrivate(false /*useRowShortcut*/, true /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
}
Graphics g = e.Graphics;
Rectangle clipRect = e.ClipRectangle;
Rectangle gridRect = this.GetGridRectangle();
if (this.currentRowSplitBar != -1)
{
clipRect = Rectangle.Union(clipRect, CalcRowResizeFeedbackRect(this.currentRowSplitBar));
}
else if (this.currentColSplitBar != -1)
{
clipRect = Rectangle.Union(clipRect, CalcColResizeFeedbackRect(this.currentColSplitBar));
}
if (clipRect.IntersectsWith(gridRect))
{
using (Region clipRegion = g.Clip)
{
g.SetClip(gridRect);
PaintBackground(g, clipRect, gridRect);
PaintGrid(g, gridRect, clipRect, this.SingleVerticalBorderAdded, this.SingleHorizontalBorderAdded);
g.Clip = clipRegion;
}
}
PaintBorder(g, clipRect, this.layout.ClientRectangle);
if (clipRect.IntersectsWith(this.layout.ResizeBoxRect))
{
g.FillRectangle(SystemBrushes.Control, this.layout.ResizeBoxRect);
}
// Draw focus rectangle around the grid
if (this.Focused && this.IsGridFocusRectangleEnabled())
{
if (SystemInformation.HighContrast)
{
ControlPaint.DrawHighContrastFocusRectangle(g, this.GetGridFocusRectangle(), SystemColors.ActiveCaptionText);
}
else
{
ControlPaint.DrawFocusRectangle(g, this.GetGridFocusRectangle());
}
}
base.OnPaint(e); // raise paint event
}
catch (Exception ex)
{
#if DEBUG
Debug.Fail("DataGridView.OnPaint exception: " + ex.Message + " stack trace " + ex.StackTrace);
#endif
if (ClientUtils.IsCriticalException(ex))
{
throw;
}
}
}
// Determines if a focus rectangle may be drawn along the perimeter of the DataGridView control
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool IsGridFocusRectangleEnabled()
{
return this.ShowFocusCues && this.CurrentCell == null && AccessibilityImprovements.Level2;
}
// Creates a rectangle by merging row headers, column headers
// and cells rectangles (from layout data)
private Rectangle GetGridRectangle()
{
Rectangle gridRect = this.layout.Data;
if (this.layout.RowHeadersVisible)
{
gridRect = Rectangle.Union(gridRect, this.layout.RowHeaders);
}
else if (this.SingleVerticalBorderAdded)
{
if (!this.RightToLeftInternal)
{
gridRect.X--;
}
gridRect.Width++;
}
if (this.layout.ColumnHeadersVisible)
{
gridRect = Rectangle.Union(gridRect, this.layout.ColumnHeaders);
}
else if (this.SingleHorizontalBorderAdded)
{
if (gridRect.Y == this.layout.Data.Y)
{
gridRect.Y--;
gridRect.Height++;
}
}
return gridRect;
}
// Creates a grid focus rectangle
private Rectangle GetGridFocusRectangle()
{
Rectangle focusRect = this.GetGridRectangle();
focusRect.Inflate(1 - FOCUS_RECT_OFFSET, 1 - FOCUS_RECT_OFFSET);
return focusRect;
}
private void InvalidateGridFocusOnScroll(int change, ScrollOrientation orientation)
{
if (change == 0)
{
return;
}
Rectangle focusRect = GetGridFocusRectangle();
if (orientation == ScrollOrientation.HorizontalScroll)
{
// Scroll right
if (change > 0)
{
focusRect.Width -= change;
}
// Scroll left
else
{
focusRect.X -= change;
focusRect.Width += change;
}
}
else
{
// Scroll down
if (change > 0)
{
focusRect.Height -= change;
}
// Scroll up
else
{
focusRect.Y -= change;
focusRect.Height += change;
}
}
this.InvalidateRectangleEdges(focusRect);
}
private void InvalidateRectangleEdges(Rectangle rect)
{
// Left edge
Rectangle edge = rect;
edge.Width = 1;
this.Invalidate(edge);
// Right edge
edge.X += rect.Width - 1;
this.Invalidate(edge);
// Top edge
edge = rect;
edge.Height = 1;
this.Invalidate(edge);
// Bottom edge
edge.Y += rect.Height - 1;
this.Invalidate(edge);
}
// See VSWhidbey 527459 & 526373.
internal override void OnParentBecameInvisible()
{
base.OnParentBecameInvisible();
if (GetState(STATE_VISIBLE))
{
// This control became invisible too - Update the Displayed properties of the bands.
OnVisibleChangedPrivate();
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnReadOnlyChanged"]/*' />
protected virtual void OnReadOnlyChanged(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWREADONLYCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
VerifyImeRestrictedModeChanged();
if (!this.ReadOnly &&
this.ptCurrentCell.X != -1 &&
ColumnEditable(this.ptCurrentCell.X) &&
!this.IsCurrentCellInEditMode &&
(this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null)) &&
!this.Rows[this.ptCurrentCell.Y].Cells[this.ptCurrentCell.X].ReadOnly) // Unshares the row
{
// Current cell becomes read/write. Enter editing mode.
BeginEditInternal(true /*selectAll*/);
}
}
internal void OnRemovedColumn_PreNotification(DataGridViewColumn dataGridViewColumn)
{
Debug.Assert(dataGridViewColumn.Index >= 0);
Debug.Assert(dataGridViewColumn.DataGridView == null);
// Clear the potential header sort glyph
if (dataGridViewColumn.HasHeaderCell)
{
dataGridViewColumn.HeaderCell.SortGlyphDirectionInternal = SortOrder.None;
}
// Intentionally keep the DisplayIndex intact after detaching the column.
CorrectColumnIndexesAfterDeletion(dataGridViewColumn);
CorrectColumnDisplayIndexesAfterDeletion(dataGridViewColumn);
// Fix the OldFirstDisplayedScrollingCol
this.displayedBandsInfo.CorrectRowIndexAfterDeletion(dataGridViewColumn.Index);
// Raise the ColumnRemoved event
OnColumnRemoved(dataGridViewColumn);
}
internal void OnRemovedColumn_PostNotification(DataGridViewColumn dataGridViewColumn, Point newCurrentCell)
{
// Update current cell if needed
if (newCurrentCell.X != -1)
{
Debug.Assert(this.ptCurrentCell.X == -1);
bool success = SetAndSelectCurrentCellAddress(newCurrentCell.X,
newCurrentCell.Y,
true,
false,
false,
false /*clearSelection*/,
false /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
// Raise SelectionChanged event if needed
FlushSelectionChanged();
// Raise ColumnStateChanged event for Displayed state of deleted column
OnColumnHidden(dataGridViewColumn);
// Columns that are removed from the collection take their non-autosized width
// Note that in some edge cases, the dev could have changed:
// - the grid's AutoSizeColumnsMode
// - the column's Width or AutoSizeMode
// in a ColumnRemoved event handler for example, in which case using the CachedThickness may be wrong.
// At least we make sure the column is not sized smaller than its minimum width.
DataGridViewAutoSizeColumnMode autoSizeColumnMode = dataGridViewColumn.GetInheritedAutoSizeMode(this);
Debug.Assert(autoSizeColumnMode != DataGridViewAutoSizeColumnMode.NotSet);
if (autoSizeColumnMode != DataGridViewAutoSizeColumnMode.None &&
autoSizeColumnMode != DataGridViewAutoSizeColumnMode.Fill &&
dataGridViewColumn.ThicknessInternal != dataGridViewColumn.CachedThickness)
{
dataGridViewColumn.ThicknessInternal = Math.Max(dataGridViewColumn.MinimumWidth, dataGridViewColumn.CachedThickness);
}
// Autosize rows if needed
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
internal void OnRemovedRow_PreNotification(int rowIndexDeleted)
{
// Fix the OldFirstDisplayedScrollingRow
this.displayedBandsInfo.CorrectRowIndexAfterDeletion(rowIndexDeleted);
CorrectRowIndexesAfterDeletion(rowIndexDeleted);
ComputeVisibleRows();
}
internal void OnRemovedRow_PostNotification(DataGridViewRow dataGridViewRow, Point newCurrentCell)
{
// Update current cell if needed
if (newCurrentCell.Y != -1)
{
Debug.Assert(this.ptCurrentCell.X == -1);
bool success = SetAndSelectCurrentCellAddress(newCurrentCell.X,
newCurrentCell.Y,
true /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/,
false /*clearSelection*/,
false /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
// Raise SelectionChange event if needed
FlushSelectionChanged();
bool rowDisplayed = dataGridViewRow.DataGridView == null && dataGridViewRow.Displayed;
// Raise RowStateChanged event for Displayed state of deleted row
if (rowDisplayed)
{
dataGridViewRow.DisplayedInternal = false;
DataGridViewRowStateChangedEventArgs dgvrsce = new DataGridViewRowStateChangedEventArgs(dataGridViewRow, DataGridViewElementStates.Displayed);
OnRowStateChanged(-1 /*rowIndex*/, dgvrsce);
}
// Rows that are removed from the collection take their non-autosized height
// Note that in some edge cases, the dev could have changed:
// - the grid's AutoSizeRowsMode
// - the row's Height
// in a RowsRemoved event handler for example, in which case using the CachedThickness may be wrong.
// At least we make sure the row is not sized smaller than its minimum height.
if (this.autoSizeRowsMode != DataGridViewAutoSizeRowsMode.None && dataGridViewRow.ThicknessInternal != dataGridViewRow.CachedThickness)
{
dataGridViewRow.ThicknessInternal = Math.Max(dataGridViewRow.MinimumHeight, dataGridViewRow.CachedThickness);
}
// Auto size columms also if needed
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFilter = DataGridViewAutoSizeColumnCriteriaInternal.AllRows;
if (rowDisplayed)
{
autoSizeColumnCriteriaFilter |= DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows;
}
bool columnAutoSized = AutoResizeAllVisibleColumnsInternal(autoSizeColumnCriteriaFilter, true /*fixedHeight*/);
bool fixedColumnHeadersHeight = this.ColumnHeadersHeightSizeMode != DataGridViewColumnHeadersHeightSizeMode.AutoSize;
bool fixedRowHeadersWidth = this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing ||
this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.DisableResizing;
if (fixedRowHeadersWidth && !columnAutoSized)
{
// No need to autosize the column headers when the row headers and columns don't change.
fixedColumnHeadersHeight = true;
}
// Auto size column headers
if (!fixedColumnHeadersHeight)
{
AutoResizeColumnHeadersHeight(fixedRowHeadersWidth, true /*fixedColumnsWidth*/);
}
// Auto size row headers
if (!fixedRowHeadersWidth)
{
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, true /*fixedRowsHeight*/);
}
if (!fixedColumnHeadersHeight && !fixedRowHeadersWidth)
{
// Second round of column headers autosizing
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
}
internal void OnRemovingColumn(DataGridViewColumn dataGridViewColumn, out Point newCurrentCell, bool force)
{
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(dataGridViewColumn.Index >= 0 && dataGridViewColumn.Index < this.Columns.Count);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell] = false;
int columnIndex = dataGridViewColumn.Index;
// Reset the current cell's address if there is one.
if (this.ptCurrentCell.X != -1)
{
int newX = this.ptCurrentCell.X;
if (columnIndex == this.ptCurrentCell.X)
{
DataGridViewColumn dataGridViewColumnNext = this.Columns.GetNextColumn(
this.Columns[columnIndex],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumnNext != null)
{
if (dataGridViewColumnNext.Index > columnIndex)
{
newX = dataGridViewColumnNext.Index - 1;
}
else
{
newX = dataGridViewColumnNext.Index;
}
}
else
{
DataGridViewColumn dataGridViewColumnPrevious = this.Columns.GetPreviousColumn(
this.Columns[columnIndex],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumnPrevious != null)
{
if (dataGridViewColumnPrevious.Index > columnIndex)
{
newX = dataGridViewColumnPrevious.Index - 1;
}
else
{
newX = dataGridViewColumnPrevious.Index;
}
}
else
{
newX = -1;
}
}
}
else if (columnIndex < this.ptCurrentCell.X)
{
newX = this.ptCurrentCell.X - 1;
}
newCurrentCell = new Point(newX, (newX == -1) ? -1 : this.ptCurrentCell.Y);
if (columnIndex == this.ptCurrentCell.X)
{
// Left cell is not validated since cancelling validation wouldn't have any effect anyways.
bool success = SetCurrentCellAddressCore(-1, -1, true /*setAnchorCellAddress*/, false /*validateCurrentCell*/, false);
Debug.Assert(success);
}
else if (force)
{
// Underlying data of deleted column is gone. It cannot be accessed anymore.
// Do not end editing mode so that CellValidation doesn't get raised, since that event needs the current formatted value.
this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell] = true;
bool success = SetCurrentCellAddressCore(-1, -1, true /*setAnchorCellAddress*/, false /*validateCurrentCell*/, false);
Debug.Assert(success);
}
else
{
// Quit editing mode and set the current cell to its new location once everything is in sync again.
ResetCurrentCell();
}
}
else
{
newCurrentCell = new Point(-1, -1);
}
// If the last column is removed, delete all the rows first.
if (this.Columns.Count == 1)
{
Debug.Assert(columnIndex == 0);
this.Rows.ClearInternal(false /*recreateNewRow*/);
}
// Prepare the existing rows by removing cells at correct index
int newColumnCount = this.Columns.Count - 1;
for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++)
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
if (dataGridViewRow.Cells.Count > newColumnCount)
{
dataGridViewRow.Cells.RemoveAtInternal(columnIndex);
}
}
// Detach column header cell
if (dataGridViewColumn.HasHeaderCell)
{
dataGridViewColumn.HeaderCell.DataGridViewInternal = null;
}
// Reset sort related variables.
if (dataGridViewColumn == this.sortedColumn)
{
this.sortedColumn = null;
this.sortOrder = SortOrder.None;
if (dataGridViewColumn.IsDataBound)
{
// If the column being removed is the sorted column and it is also the dataBound column
// then see if there is another dataBound column which has the same property name as the sorted column.
// If so, then make that dataGridViewColumn the sorted column in the data grid view.
for (int i = 0; i < this.Columns.Count; i ++)
{
if (dataGridViewColumn != this.Columns[i] &&
this.Columns[i].SortMode != DataGridViewColumnSortMode.NotSortable &&
String.Compare(dataGridViewColumn.DataPropertyName,
this.Columns[i].DataPropertyName,
true /*ignoreCase*/,
CultureInfo.InvariantCulture) == 0)
{
Debug.Assert(this.Columns[i].IsDataBound, "two columns w/ the same DataPropertyName should be DataBound at the same time");
Debug.Assert(this.Columns[i].HeaderCell.SortGlyphDirection == dataGridViewColumn.HeaderCell.SortGlyphDirection, "DataBound columns should have the same SortGlyphDirection as the one on the DataGridView");
this.sortedColumn = this.Columns[i];
this.sortOrder = this.Columns[i].HeaderCell.SortGlyphDirection;
break;
}
}
}
}
// Is deleted column scrolled off screen?
if (dataGridViewColumn.Visible &&
!dataGridViewColumn.Frozen &&
this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0)
{
// Deleted column is part of scrolling columns.
if (this.displayedBandsInfo.FirstDisplayedScrollingCol == dataGridViewColumn.Index)
{
// Deleted column is first scrolling column
this.horizontalOffset -= this.negOffset;
this.negOffset = 0;
}
else if (this.Columns.DisplayInOrder(this.displayedBandsInfo.FirstDisplayedScrollingCol, dataGridViewColumn.Index))
{
// Deleted column is displayed after first scrolling column
if (this.horizScrollBar.Enabled)
{
int newHorizontalOffset = this.horizScrollBar.Maximum - this.horizScrollBar.LargeChange - dataGridViewColumn.Thickness;
if (newHorizontalOffset >= 0 && newHorizontalOffset < this.horizScrollBar.Value)
{
this.horizontalOffset = newHorizontalOffset;
this.negOffset = GetNegOffsetFromHorizontalOffset(this.horizontalOffset);
}
}
else
{
this.horizontalOffset = this.negOffset = 0;
}
}
else
{
// Deleted column is displayed before first scrolling column
Debug.Assert(this.horizontalOffset >= dataGridViewColumn.Thickness);
this.horizontalOffset -= dataGridViewColumn.Thickness;
}
if (this.horizScrollBar.Enabled)
{
this.horizScrollBar.Value = this.horizontalOffset;
}
}
bool raiseSelectionChanged = false;
// Update the indexes of selected columns or individual cells to compensate for the removal of this column
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
int columnEntries = this.selectedBandIndexes.Count;
int columnEntry = 0;
while (columnEntry < columnEntries)
{
int columnIndexSelected = this.selectedBandIndexes[columnEntry];
if (columnIndex == columnIndexSelected)
{
this.selectedBandIndexes.RemoveAt(columnEntry);
columnEntries--;
raiseSelectionChanged = true;
}
else
{
if (columnIndex < columnIndexSelected)
{
this.selectedBandIndexes[columnEntry] = columnIndexSelected - 1;
}
columnEntry++;
}
}
break;
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_raiseSelectionChanged] |= this.individualSelectedCells.RemoveAllCellsAtBand(true /*column*/, columnIndex) > 0 ||
raiseSelectionChanged;
this.individualReadOnlyCells.RemoveAllCellsAtBand(true /*column*/, columnIndex);
}
internal void OnRemovingRow(int rowIndexDeleted, out Point newCurrentCell, bool force)
{
// if force is true, the row needs to be deleted no matter what. The underlying data row was already deleted.
Debug.Assert(rowIndexDeleted >= 0 && rowIndexDeleted < this.Rows.Count);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell] = false;
newCurrentCell = new Point(-1, -1);
// Reset the current cell's address if it's on the deleted row, or after it.
if (this.ptCurrentCell.Y != -1 && rowIndexDeleted <= this.ptCurrentCell.Y)
{
int newY;
if (rowIndexDeleted == this.ptCurrentCell.Y)
{
int rowIndexPrevious = this.Rows.GetPreviousRow(rowIndexDeleted, DataGridViewElementStates.Visible);
int rowIndexNext = this.Rows.GetNextRow(rowIndexDeleted, DataGridViewElementStates.Visible);
if (rowIndexPrevious > -1 && this.AllowUserToAddRowsInternal)
{
Debug.Assert(this.newRowIndex != -1);
Debug.Assert(this.newRowIndex == this.Rows.Count-1);
if (rowIndexNext > -1 && rowIndexNext < this.Rows.Count - 1)
{
newY = rowIndexNext - 1;
}
else
{
newY = rowIndexPrevious;
}
}
else
{
if (rowIndexNext > -1)
{
newY = rowIndexNext - 1;
}
else
{
newY = rowIndexPrevious;
}
}
// Since the current row is deleted, the dirty states need to be reset
this.IsCurrentCellDirtyInternal = false;
this.IsCurrentRowDirtyInternal = false;
}
else
{
Debug.Assert(rowIndexDeleted < this.ptCurrentCell.Y);
newY = this.ptCurrentCell.Y - 1;
}
newCurrentCell = new Point(this.ptCurrentCell.X, newY);
if (rowIndexDeleted == this.ptCurrentCell.Y)
{
// Left cell is not validated since cancelling validation wouldn't have any effect anyways.
bool success = SetCurrentCellAddressCore(-1, -1, true /*setAnchorCellAddress*/, false /*validateCurrentCell*/, false);
Debug.Assert(success);
}
else if (force)
{
// Underlying data of deleted row is gone. It cannot be accessed anymore.
// Do not end editing mode so that CellValidation doesn't get raised, since that event needs the current formatted value.
this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell] = true;
bool success = SetCurrentCellAddressCore(-1, -1, true /*setAnchorCellAddress*/, false /*validateCurrentCell*/, false);
Debug.Assert(success);
}
else
{
// Quit editing mode and set the current cell to its new location once everything is in sync again.
ResetCurrentCell();
}
}
bool raiseSelectionChanged = false;
// Update the indexes of selected rows to compensate for the removal of this row
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
int rowEntries = this.selectedBandIndexes.Count;
int rowEntry = 0;
while (rowEntry < rowEntries)
{
int rowIndex = this.selectedBandIndexes[rowEntry];
if (rowIndexDeleted == rowIndex)
{
raiseSelectionChanged = true;
this.selectedBandIndexes.RemoveAt(rowEntry);
rowEntries--;
}
else
{
if (rowIndexDeleted < rowIndex)
{
this.selectedBandIndexes[rowEntry] = rowIndex - 1;
}
rowEntry++;
}
}
if (this.selectedBandSnapshotIndexes != null)
{
rowEntries = this.selectedBandSnapshotIndexes.Count;
rowEntry = 0;
while (rowEntry < rowEntries)
{
int rowIndex = this.selectedBandSnapshotIndexes[rowEntry];
if (rowIndexDeleted == rowIndex)
{
this.selectedBandSnapshotIndexes.RemoveAt(rowEntry);
rowEntries--;
}
else
{
if (rowIndexDeleted < rowIndex)
{
this.selectedBandSnapshotIndexes[rowEntry] = rowIndex - 1;
}
rowEntry++;
}
}
}
break;
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_raiseSelectionChanged] |= this.individualSelectedCells.RemoveAllCellsAtBand(false /*column*/, rowIndexDeleted) > 0 ||
raiseSelectionChanged;
this.individualReadOnlyCells.RemoveAllCellsAtBand(false /*column*/, rowIndexDeleted);
}
internal void OnReplacedCell(DataGridViewRow dataGridViewRow, int columnIndex)
{
DataGridViewCell dataGridViewCell = dataGridViewRow.Cells[columnIndex];
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_replacedCellSelected])
{
this.individualSelectedCells.Add(dataGridViewCell);
}
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_replacedCellReadOnly])
{
this.individualReadOnlyCells.Add(dataGridViewCell);
}
// AutoSize column and row if needed
OnCellCommonChange(columnIndex, dataGridViewRow.Index);
if (this.ptCurrentCellCache.X != -1)
{
if (!IsInnerCellOutOfBounds(this.ptCurrentCellCache.X, this.ptCurrentCellCache.Y))
{
SetCurrentCellAddressCore(this.ptCurrentCellCache.X, this.ptCurrentCellCache.Y, false, false, false);
}
this.ptCurrentCellCache.X = -1;
this.ptCurrentCellCache.Y = -1;
}
}
internal void OnReplacingCell(DataGridViewRow dataGridViewRow, int columnIndex)
{
if (this.ptCurrentCell.X == dataGridViewRow.Index &&
this.ptCurrentCell.Y == columnIndex)
{
// Trying to replace the current cell. Exiting editing mode first (if needed).
// Remember to reset the current cell in OnReplacedCell notification
this.ptCurrentCellCache.X = this.ptCurrentCell.X;
this.ptCurrentCellCache.Y = this.ptCurrentCell.Y;
// This may fail and throw an exception
ResetCurrentCell();
}
else
{
this.ptCurrentCellCache.X = -1;
this.ptCurrentCellCache.Y = -1;
}
DataGridViewCell dataGridViewCell = dataGridViewRow.Cells[columnIndex];
this.dataGridViewState2[DATAGRIDVIEWSTATE2_replacedCellSelected] = this.individualSelectedCells.Contains(dataGridViewCell);
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_replacedCellSelected])
{
this.individualSelectedCells.Remove(dataGridViewCell);
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_replacedCellReadOnly] = this.individualReadOnlyCells.Contains(dataGridViewCell);
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_replacedCellReadOnly])
{
this.individualReadOnlyCells.Remove(dataGridViewCell);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnResize"]/*' />
protected override void OnResize(EventArgs e)
{
int borderWidth = this.BorderWidth;
Rectangle right;
Rectangle bottom;
Rectangle oldClientRectangle = this.layout.ClientRectangle;
Rectangle oldGridFocusRectangle = this.GetGridFocusRectangle();
right = new Rectangle(oldClientRectangle.X + oldClientRectangle.Width - borderWidth,
oldClientRectangle.Y,
borderWidth,
oldClientRectangle.Height);
bottom = new Rectangle(oldClientRectangle.X,
oldClientRectangle.Y + oldClientRectangle.Height - borderWidth,
oldClientRectangle.Width,
borderWidth);
if (!this.IsMinimized)
{
// When owning form is minimized, act as if it had a normal size
this.normalClientRectangle = this.ClientRectangle;
}
Rectangle newClientRectangle = this.normalClientRectangle;
Rectangle newGridFocusRectangle = this.DisplayRectangle;
newGridFocusRectangle.Inflate(1 - borderWidth - FOCUS_RECT_OFFSET, 1 - borderWidth - FOCUS_RECT_OFFSET);
if (newClientRectangle.Width != oldClientRectangle.Width)
{
Invalidate(right);
right = new Rectangle(newClientRectangle.X + newClientRectangle.Width - borderWidth,
newClientRectangle.Y,
borderWidth,
newClientRectangle.Height);
Invalidate(right);
}
if (newClientRectangle.Height != oldClientRectangle.Height)
{
Invalidate(bottom);
bottom = new Rectangle(newClientRectangle.X,
newClientRectangle.Y + newClientRectangle.Height - borderWidth,
newClientRectangle.Width,
borderWidth);
Invalidate(bottom);
}
// Invalidate grid focus rectangle
if (this.Focused && this.IsGridFocusRectangleEnabled() && oldGridFocusRectangle != newGridFocusRectangle)
{
right = new Rectangle(oldGridFocusRectangle.X + oldGridFocusRectangle.Width - 1,
oldGridFocusRectangle.Y,
1,
oldGridFocusRectangle.Height);
Invalidate(right);
bottom = new Rectangle(oldGridFocusRectangle.X,
oldGridFocusRectangle.Y + oldGridFocusRectangle.Height - 1,
oldGridFocusRectangle.Width,
1);
Invalidate(bottom);
InvalidateRectangleEdges(newGridFocusRectangle);
}
//also, invalidate the ResizeBoxRect
if (!this.layout.ResizeBoxRect.IsEmpty)
{
Invalidate(this.layout.ResizeBoxRect);
}
this.layout.ClientRectangle = newClientRectangle;
int oldfirstDisplayedScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
base.OnResize(e);
if (oldfirstDisplayedScrollingRow != this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
Invalidate();
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRightToLeftChanged"]/*' />
protected override void OnRightToLeftChanged(EventArgs e)
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_rightToLeftValid] = false;
base.OnRightToLeftChanged(e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
}
internal void OnRowCollectionChanged_PostNotification(bool recreateNewRow,
bool allowSettingCurrentCell,
CollectionChangeAction cca,
DataGridViewRow dataGridViewRow,
int rowIndex)
{
if (recreateNewRow &&
cca == CollectionChangeAction.Refresh &&
this.Columns.Count != 0 &&
this.Rows.Count == 0 &&
this.AllowUserToAddRowsInternal)
{
AddNewRow(false);
}
if (cca == CollectionChangeAction.Refresh)
{
FlushSelectionChanged();
}
if ((cca == CollectionChangeAction.Refresh || cca == CollectionChangeAction.Add) &&
this.ptCurrentCell.X == -1 && allowSettingCurrentCell && !this.InSortOperation)
{
MakeFirstDisplayedCellCurrentCell(false /*includeNewRow*/);
}
if (this.AutoSize)
{
bool invalidatePreferredSizeCache = true;
switch (cca)
{
case CollectionChangeAction.Add:
Debug.Assert(rowIndex >= 0);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
invalidatePreferredSizeCache = ((rowState & DataGridViewElementStates.Visible) != 0);
break;
case CollectionChangeAction.Remove:
invalidatePreferredSizeCache = dataGridViewRow.DataGridView == null && dataGridViewRow.Visible;
break;
// case CollectionChangeAction.Refresh: invalidatePreferredSizeCache stays true
}
if (invalidatePreferredSizeCache)
{
LayoutTransaction.DoLayout(this.ParentInternal, this, PropertyNames.Rows);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowContextMenuStripChanged"]/*' />
protected virtual void OnRowContextMenuStripChanged(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWCONTEXTMENUSTRIPCHANGED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal ContextMenuStrip OnRowContextMenuStripNeeded(int rowIndex, ContextMenuStrip contextMenuStrip)
{
DataGridViewRowContextMenuStripNeededEventArgs dgvrcmsne = new DataGridViewRowContextMenuStripNeededEventArgs(rowIndex, contextMenuStrip);
OnRowContextMenuStripNeeded(dgvrcmsne);
return dgvrcmsne.ContextMenuStrip;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowContextMenuStripNeeded"]/*' />
protected virtual void OnRowContextMenuStripNeeded(DataGridViewRowContextMenuStripNeededEventArgs e)
{
DataGridViewRowContextMenuStripNeededEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWCONTEXTMENUSTRIPNEEDED] as DataGridViewRowContextMenuStripNeededEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowDefaultCellStyleChanged"]/*' />
protected virtual void OnRowDefaultCellStyleChanged(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
OnRowGlobalAutoSize(e.Row.Index);
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWDEFAULTCELLSTYLECHANGED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowDirtyStateNeeded"]/*' />
protected virtual void OnRowDirtyStateNeeded(QuestionEventArgs e)
{
QuestionEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWDIRTYSTATENEEDED] as QuestionEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowDividerDoubleClick"]/*' />
protected virtual void OnRowDividerDoubleClick(DataGridViewRowDividerDoubleClickEventArgs e)
{
DataGridViewRowDividerDoubleClickEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWDIVIDERDOUBLECLICK] as DataGridViewRowDividerDoubleClickEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (!e.Handled && e.Button == MouseButtons.Left && e.RowIndex < this.Rows.Count)
{
if (e.RowIndex == -1)
{
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
else
{
if (this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
{
AutoResizeRowInternal(e.RowIndex, DataGridViewAutoSizeRowMode.AllCells, true /*fixedWidth*/, true /*internalAutosizing*/);
}
else
{
AutoResizeRowInternal(e.RowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), true /*fixedWidth*/, true /*internalAutosizing*/);
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowDividerHeightChanged"]/*' />
protected virtual void OnRowDividerHeightChanged(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
OnRowGlobalAutoSize(e.Row.Index);
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWDIVIDERHEIGHTCHANGED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnRowEnter(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex, bool canCreateNewRow, bool validationFailureOccurred)
{
Debug.Assert(columnIndex >= 0 && rowIndex >= 0);
if (!validationFailureOccurred)
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowEdited] = false;
}
if (rowIndex < this.Rows.Count &&
columnIndex < this.Columns.Count)
{
bool calledAddNewOnTheDataConnection = false;
if (!validationFailureOccurred && this.AllowUserToAddRowsInternal && this.newRowIndex == rowIndex)
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowEdited] = true;
if (canCreateNewRow)
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs(this.Rows[this.newRowIndex]);
if (this.VirtualMode || this.DataSource != null)
{
if (this.dataConnection != null && this.dataConnection.InterestedInRowEvents)
{
this.dataConnection.OnNewRowNeeded();
calledAddNewOnTheDataConnection = true;
}
if (this.VirtualMode)
{
OnNewRowNeeded(dgvre);
}
}
// vsWhidbey 329429: AllowUserToAddRowsInternal can become FALSE while adding a row.
// NOTE: we don't need to invalidate if AllowUserToAddRowsInternal changed to FALSE.
//
if (this.AllowUserToAddRowsInternal)
{
OnDefaultValuesNeeded(dgvre);
InvalidateRowPrivate(this.newRowIndex);
}
#if DEBUG
else
{
Debug.Assert(this.newRowIndex == -1, "newRowIndex and AllowUserToAddRowsInternal became out of sync");
}
#endif //
}
}
if (calledAddNewOnTheDataConnection && rowIndex > this.Rows.Count - 1)
{
// Calling AddNew on the DataConnection can result in the entire list being wiped out.
//
rowIndex = Math.Min(rowIndex, this.Rows.Count - 1);
}
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(columnIndex, rowIndex);
OnRowEnter(dgvce);
if (this.dataConnection != null &&
this.dataConnection.InterestedInRowEvents &&
!this.dataConnection.PositionChangingOutsideDataGridView &&
!this.dataConnection.ListWasReset &&
(!calledAddNewOnTheDataConnection || this.dataConnection.List.Count > 0))
{
this.dataConnection.OnRowEnter(dgvce);
}
if (dataGridViewCell != null)
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
dataGridViewCell = null;
}
else
{
Debug.Assert(rowIndex < this.Rows.Count && columnIndex < this.Columns.Count);
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowEnter"]/*' />
protected virtual void OnRowEnter(DataGridViewCellEventArgs e)
{
try
{
this.noDimensionChangeCount++;
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWENTER] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
}
}
internal void OnRowErrorTextChanged(DataGridViewRow dataGridViewRow)
{
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs(dataGridViewRow);
OnRowErrorTextChanged(dgvre);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowErrorTextChanged"]/*' />
protected virtual void OnRowErrorTextChanged(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
UpdateRowErrorText(e.Row.Index);
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWERRORTEXTCHANGED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal string OnRowErrorTextNeeded(int rowIndex, string errorText)
{
Debug.Assert(rowIndex >= 0);
DataGridViewRowErrorTextNeededEventArgs dgvretne = new DataGridViewRowErrorTextNeededEventArgs(rowIndex, errorText);
OnRowErrorTextNeeded(dgvretne);
return dgvretne.ErrorText;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowErrorTextNeeded"]/*' />
protected virtual void OnRowErrorTextNeeded(DataGridViewRowErrorTextNeededEventArgs e)
{
DataGridViewRowErrorTextNeededEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWERRORTEXTNEEDED] as DataGridViewRowErrorTextNeededEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnRowGlobalAutoSize(int rowIndex)
{
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if ((rowState & DataGridViewElementStates.Visible) == 0)
{
return;
}
InvalidateRowPrivate(rowIndex);
if (this.noAutoSizeCount > 0)
{
return;
}
DataGridViewAutoSizeRowsModeInternal autoSizeRowsModeInternal = (DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode;
bool autoSizeRow = false;
bool rowDisplayed = (rowState & DataGridViewElementStates.Displayed) != 0;
if (autoSizeRowsModeInternal != DataGridViewAutoSizeRowsModeInternal.None &&
!((autoSizeRowsModeInternal & DataGridViewAutoSizeRowsModeInternal.DisplayedRows) != 0 && !rowDisplayed))
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), false /*fixedWidth*/, true /*internalAutosizing*/);
autoSizeRow = true;
}
// Auto size columms also if needed
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFilter = DataGridViewAutoSizeColumnCriteriaInternal.AllRows;
if (rowDisplayed)
{
autoSizeColumnCriteriaFilter |= DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows;
}
AutoResizeAllVisibleColumnsInternal(autoSizeColumnCriteriaFilter, true /*fixedHeight*/);
bool fixedRowHeadersWidth = this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing ||
this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.DisableResizing;
// Auto size column headers
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(fixedRowHeadersWidth, true /*fixedColumnsWidth*/);
}
// Auto size row headers
if (!fixedRowHeadersWidth)
{
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, true /*fixedRowsHeight*/);
}
if (autoSizeRow)
{
// Second round of row autosizing
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize && !fixedRowHeadersWidth)
{
// Second round of column headers autosizing
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeaderCellChanged"]/*' />
protected virtual void OnRowHeaderCellChanged(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
OnRowHeaderGlobalAutoSize(e.Row.Index);
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEADERCELLCHANGED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnRowHeaderGlobalAutoSize(int rowIndex)
{
if (!this.RowHeadersVisible)
{
return;
}
InvalidateCellPrivate(-1, rowIndex);
if (this.noAutoSizeCount > 0)
{
return;
}
bool rowDisplayed = false;
if (rowIndex != -1)
{
rowDisplayed = (this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Displayed) != 0;
}
bool fixedColumnHeadersHeight = rowIndex != -1 || this.ColumnHeadersHeightSizeMode != DataGridViewColumnHeadersHeightSizeMode.AutoSize;
bool fixedRowHeight = rowIndex == -1 ||
((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.Header) == 0) ||
((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.DisplayedRows) != 0 && rowIndex != -1 && !rowDisplayed);
bool autoSizeRowHeaders = false;
if (this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders ||
(this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders && rowIndex != -1 && rowDisplayed) ||
(this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.EnableResizing && this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.DisableResizing && rowIndex == -1) ||
(this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader && rowIndex != -1 && rowIndex == this.Rows.GetFirstRow(DataGridViewElementStates.Visible)))
{
AutoResizeRowHeadersWidth(rowIndex,
this.rowHeadersWidthSizeMode,
fixedColumnHeadersHeight,
fixedRowHeight);
autoSizeRowHeaders = true;
}
if (!fixedColumnHeadersHeight)
{
AutoResizeColumnHeadersHeight(-1, true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
if (!fixedRowHeight)
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (autoSizeRowHeaders && (!fixedColumnHeadersHeight || !fixedRowHeight))
{
// Second round of row headers autosizing
AutoResizeRowHeadersWidth(rowIndex,
this.rowHeadersWidthSizeMode,
true /*fixedColumnHeadersHeight*/,
true /*fixedRowHeight*/);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeaderMouseClick"]/*' />
protected virtual void OnRowHeaderMouseClick(DataGridViewCellMouseEventArgs e)
{
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEADERMOUSECLICK] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeaderMouseDoubleClick"]/*' />
protected virtual void OnRowHeaderMouseDoubleClick(DataGridViewCellMouseEventArgs e)
{
DataGridViewCellMouseEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEADERMOUSEDOUBLECLICK] as DataGridViewCellMouseEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnRowHeaderMouseDown(HitTestInfo hti, bool isShiftDown, bool isControlDown)
{
Debug.Assert(hti.Type == DataGridViewHitTestType.RowHeader);
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
break;
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
bool select = true;
if (isControlDown &&
((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Selected) != 0))
{
select = false;
}
if (select)
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
if (dataGridViewColumn != null && hti.row != this.ptCurrentCell.Y)
{
int oldCurrentCellX = this.ptCurrentCell.X;
int oldCurrentCellY = this.ptCurrentCell.Y;
// Make sure we will be able to scroll into view
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.CurrentCellChange,
DataGridViewValidateCellInternal.Always /*validateCell*/,
true /*fireCellLeave*/,
true /*fireCellEnter*/,
hti.row != this.ptCurrentCell.Y /*fireRowLeave*/,
hti.row != this.ptCurrentCell.Y /*fireRowEnter*/,
false /*fireLeave*/,
this.EditMode != DataGridViewEditMode.EditOnEnter /*keepFocus*/,
true /*resetCurrentCell*/,
false /*resetAnchorCell*/))
{
// Just cancel operation silently instead of throwing InvalidOperationException
return;
}
if (oldCurrentCellY != -1)
{
DataGridViewCell dataGridViewCellTmp = null;
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
if (OnRowValidating(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY))
{
// Row validation was cancelled
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
OnRowEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY, true /*canCreateNewRow*/, true /*validationFailureOccurred*/);
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
OnCellEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
return;
}
if (IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
return;
}
OnRowValidated(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
// Row validation was not cancelled, but operation needs to be re-evaluated.
if (hti.row >= this.Rows.Count)
{
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
if (this.ptCurrentCell.X == -1 && lastVisibleRowIndex != -1)
{
// CurrentCell was reset because commit deleted row(s).
// Since the user wants to select a row, 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'.
if (IsColumnOutOfBounds(oldCurrentCellX))
{
return;
}
bool success = SetAndSelectCurrentCellAddress(oldCurrentCellX,
lastVisibleRowIndex,
true,
false,
false,
false /*clearSelection*/,
false /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
return;
}
else if ((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Visible) == 0)
{
return;
}
}
}
bool selectRowRange = false;
this.trackRow = hti.row;
this.trackRowEdge = -1;
if (this.MultiSelect &&
isShiftDown &&
this.ptAnchorCell.Y > -1 &&
(this.Rows.GetRowState(this.ptAnchorCell.Y) & DataGridViewElementStates.Selected) != 0)
{
selectRowRange = true;
}
if (!this.MultiSelect || !isControlDown || isShiftDown)
{
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != hti.row)
{
// deselect currently selected row
SetSelectedRowCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
if (this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect)
{
RemoveIndividuallySelectedCells();
}
else
{
Debug.Assert(this.individualSelectedCells.Count == 0);
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
if (this.MultiSelect && this.dataGridViewOper[DATAGRIDVIEWOPER_trackMouseMoves])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] = true;
}
if (selectRowRange)
{
if (hti.row >= this.ptAnchorCell.Y)
{
SelectRowRange(this.ptAnchorCell.Y, hti.row, true);
}
else
{
SelectRowRange(hti.row, this.ptAnchorCell.Y, true);
}
}
else if ((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Selected) == 0)
{
Debug.Assert(this.selectedBandIndexes.Contains(hti.row) ==
((this.Rows.GetRowState(hti.row) & DataGridViewElementStates.Selected) != 0));
SetSelectedRowCore(hti.row, true);
}
if (dataGridViewColumn != null)
{
if (hti.row != this.ptCurrentCell.Y)
{
if (IsInnerCellOutOfBounds(dataGridViewColumn.Index, hti.row))
{
return;
}
// set current cell to the left most visible cell in the row
bool success = ScrollIntoView(dataGridViewColumn.Index, hti.row, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(dataGridViewColumn.Index, hti.row))
{
return;
}
success = SetCurrentCellAddressCore(dataGridViewColumn.Index, hti.row, !selectRowRange, false, true);
Debug.Assert(success);
}
else if (-1 != this.ptCurrentCell.Y)
{
// Potentially have to give focus back to the current edited cell.
bool success = SetCurrentCellAddressCore(this.ptCurrentCell.X, this.ptCurrentCell.Y,
false /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/);
Debug.Assert(success);
}
}
else
{
Debug.Assert(this.CurrentCellAddress == new Point(-1, -1));
}
}
else
{
Debug.Assert(this.selectedBandIndexes.Contains(hti.row));
SetSelectedRowCore(hti.row, false);
}
break;
}
}
}
finally
{
this.NoSelectionChangeCount--;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeadersBorderStyleChanged"]/*' />
protected virtual void OnRowHeadersBorderStyleChanged(EventArgs e)
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, false /*repositionEditingControl*/);
Invalidate();
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEADERSBORDERSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeadersDefaultCellStyleChanged"]/*' />
protected virtual void OnRowHeadersDefaultCellStyleChanged(EventArgs e)
{
if (this.RowHeadersVisible)
{
Invalidate(Rectangle.Union(this.layout.TopLeftHeader, this.layout.RowHeaders));
DataGridViewCellStyleChangedEventArgs dgvcsce = e as DataGridViewCellStyleChangedEventArgs;
if (dgvcsce == null || dgvcsce.ChangeAffectsPreferredSize)
{
OnRowHeadersGlobalAutoSize(false /*expandingRows*/);
if (this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEADERSDEFAULTCELLSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnRowHeadersGlobalAutoSize(bool expandingRows)
{
if (this.noAutoSizeCount > 0)
{
return;
}
bool fixedRowsHeight = (((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.Header) == 0 ||
!this.RowHeadersVisible;
bool autoSizeRowHeaders = this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.EnableResizing &&
this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.DisableResizing;
if (autoSizeRowHeaders)
{
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, fixedRowsHeight);
}
if (!fixedRowsHeight)
{
if (expandingRows)
{
AdjustExpandingRows(-1, true /*fixedWidth*/);
}
else
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (autoSizeRowHeaders)
{
// Second round of row headers autosizing
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, true /*fixedRowsHeight*/);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeadersWidthChanged"]/*' />
protected virtual void OnRowHeadersWidthChanged(EventArgs e)
{
if (this.RowHeadersVisible)
{
if (this.editingControl != null)
{
PositionEditingControl(true, false, false);
}
if (this.IsHandleCreated)
{
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
}
OnRowHeadersGlobalAutoSize(false /*expandingRows*/);
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEADERSWIDTHCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeadersWidthSizeModeChanged"]/*' />
protected virtual void OnRowHeadersWidthSizeModeChanged(DataGridViewAutoSizeModeEventArgs e)
{
if (this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.EnableResizing &&
this.rowHeadersWidthSizeMode != DataGridViewRowHeadersWidthSizeMode.DisableResizing)
{
if (!e.PreviousModeAutoSized)
{
// Save current row headers width for later reuse
this.cachedRowHeadersWidth = this.RowHeadersWidth;
}
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode,
true /*fixedColumnHeadersHeight*/,
true /*fixedRowsHeight*/);
}
else if (e.PreviousModeAutoSized)
{
this.RowHeadersWidth = this.cachedRowHeadersWidth;
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEADERSWIDTHSIZEMODECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeightChanged"]/*' />
protected virtual void OnRowHeightChanged(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
UpdateRowHeightInfoPrivate(e.Row.Index, false, false /*invalidInAdjustFillingColumns*/);
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEIGHTCHANGED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
OnRowGlobalAutoSize(e.Row.Index);
}
internal DataGridViewRowHeightInfoNeededEventArgs OnRowHeightInfoNeeded(int rowIndex, int height, int minimumHeight)
{
DataGridViewRowHeightInfoNeededEventArgs dgvrhine = this.RowHeightInfoNeededEventArgs;
dgvrhine.SetProperties(rowIndex, height, minimumHeight);
OnRowHeightInfoNeeded(dgvrhine);
return dgvrhine;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeightInfoNeeded"]/*' />
protected virtual void OnRowHeightInfoNeeded(DataGridViewRowHeightInfoNeededEventArgs e)
{
DataGridViewRowHeightInfoNeededEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEIGHTINFONEEDED] as DataGridViewRowHeightInfoNeededEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private bool OnRowHeightInfoPushed(int rowIndex, int height, int minimumHeight)
{
Debug.Assert(rowIndex != -1);
Debug.Assert(this.autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None);
if (this.VirtualMode || this.DataSource != null)
{
DataGridViewRowHeightInfoPushedEventArgs dgvrhipe = new DataGridViewRowHeightInfoPushedEventArgs(rowIndex, height, minimumHeight);
OnRowHeightInfoPushed(dgvrhipe);
if (dgvrhipe.Handled)
{
UpdateRowHeightInfoPrivate(rowIndex, false, true /*invalidInAdjustFillingColumns*/);
return true;
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowHeightInfoPushed"]/*' />
protected virtual void OnRowHeightInfoPushed(DataGridViewRowHeightInfoPushedEventArgs e)
{
DataGridViewRowHeightInfoPushedEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWHEIGHTINFOPUSHED] as DataGridViewRowHeightInfoPushedEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnRowLeave(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex)
{
Debug.Assert(columnIndex >= 0 && rowIndex >= 0);
if (rowIndex < this.Rows.Count && columnIndex < this.Columns.Count)
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(columnIndex, rowIndex);
OnRowLeave(dgvce);
if (dataGridViewCell != null)
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
dataGridViewCell = null;
}
else
{
Debug.Assert(rowIndex < this.Rows.Count && columnIndex < this.Columns.Count);
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowLeave"]/*' />
protected virtual void OnRowLeave(DataGridViewCellEventArgs e)
{
try
{
this.noDimensionChangeCount++;
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWLEAVE] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowMinimumHeightChanged"]/*' />
protected virtual void OnRowMinimumHeightChanged(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWMINIMUMHEIGHTCHANGED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowPostPaint"]/*' />
protected internal virtual void OnRowPostPaint(DataGridViewRowPostPaintEventArgs e)
{
DataGridViewRowPostPaintEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWPOSTPAINT] as DataGridViewRowPostPaintEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowPrePaint"]/*' />
protected internal virtual void OnRowPrePaint(DataGridViewRowPrePaintEventArgs e)
{
DataGridViewRowPrePaintEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWPREPAINT] as DataGridViewRowPrePaintEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnRowsAddedInternal(int rowIndex, int rowCount)
{
OnRowsAdded(new DataGridViewRowsAddedEventArgs(rowIndex, rowCount));
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowsAdded"]/*' />
protected virtual void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
{
DataGridViewRowsAddedEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWSADDED] as DataGridViewRowsAddedEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowsDefaultCellStyleChanged"]/*' />
protected virtual void OnRowsDefaultCellStyleChanged(EventArgs e)
{
DataGridViewCellStyleChangedEventArgs dgvcsce = e as DataGridViewCellStyleChangedEventArgs;
if (dgvcsce != null && !dgvcsce.ChangeAffectsPreferredSize)
{
InvalidateData();
}
else
{
OnRowsGlobalAutoSize();
if (this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWSDEFAULTCELLSTYLECHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnRowSelectMouseMove(HitTestInfo hti)
{
Debug.Assert(hti.row >= 0);
Debug.Assert(this.MultiSelect);
if (this.ptCurrentCell.Y != -1 &&
hti.row != this.ptCurrentCell.Y &&
!CommitEditForOperation(this.ptCurrentCell.X, hti.row, true))
{
// Return silently if validating/commit/abort failed
return;
}
if (IsRowOutOfBounds(hti.row))
{
return;
}
this.noSelectionChangeCount++;
try
{
if (this.trackRowEdge >= this.trackRow && hti.row > this.trackRowEdge && this.trackRowEdge >= 0)
{
SelectRowRange(this.Rows.GetNextRow(this.trackRowEdge, DataGridViewElementStates.Visible),
hti.row, true);
this.trackRowEdge = hti.row;
}
else if (this.trackRowEdge > this.trackRow && hti.row < this.trackRowEdge && hti.row >= this.trackRow && this.trackRowEdge >= 0)
{
SelectRowRange(this.Rows.GetNextRow(hti.row, DataGridViewElementStates.Visible),
this.trackRowEdge, false);
this.trackRowEdge = hti.row;
}
else if (hti.row > this.trackRow && this.trackRowEdge == -1)
{
SelectRowRange(this.Rows.GetNextRow(this.trackRow, DataGridViewElementStates.Visible),
hti.row, true);
this.trackRowEdge = hti.row;
}
else if (this.trackRowEdge <= this.trackRow && hti.row < this.trackRowEdge && this.trackRowEdge >= 0)
{
SelectRowRange(hti.row,
this.Rows.GetPreviousRow(this.trackRowEdge, DataGridViewElementStates.Visible),
true);
this.trackRowEdge = hti.row;
}
else if (this.trackRowEdge < this.trackRow && hti.row > this.trackRowEdge && hti.row <= this.trackRow && this.trackRowEdge >= 0)
{
SelectRowRange(this.trackRowEdge,
this.Rows.GetPreviousRow(hti.row, DataGridViewElementStates.Visible),
false);
this.trackRowEdge = hti.row;
}
else if (hti.row < this.trackRow && this.trackRowEdge == -1)
{
SelectRowRange(hti.row,
this.Rows.GetPreviousRow(this.trackRow, DataGridViewElementStates.Visible),
true);
this.trackRowEdge = hti.row;
}
else if (this.trackRowEdge > this.trackRow && hti.row < this.trackRow)
{
SelectRowRange(this.Rows.GetNextRow(this.trackRow, DataGridViewElementStates.Visible),
this.trackRowEdge, false);
SelectRowRange(hti.row,
this.Rows.GetPreviousRow(this.trackRow, DataGridViewElementStates.Visible),
true);
this.trackRowEdge = hti.row;
}
else if (hti.row > this.trackRow && this.trackRowEdge < this.trackRow && this.trackRowEdge >= 0)
{
SelectRowRange(this.trackRowEdge,
this.Rows.GetPreviousRow(this.trackRow, DataGridViewElementStates.Visible),
false);
SelectRowRange(this.Rows.GetNextRow(this.trackRow, DataGridViewElementStates.Visible),
hti.row, true);
this.trackRowEdge = hti.row;
}
}
finally
{
this.NoSelectionChangeCount--;
}
if (this.ptCurrentCell.Y != -1 && hti.row != this.ptCurrentCell.Y)
{
if (IsRowOutOfBounds(hti.row))
{
return;
}
bool success = SetCurrentCellAddressCore(this.ptCurrentCell.X,
hti.row,
false /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/);
Debug.Assert(success);
}
}
private void OnRowsGlobalAutoSize()
{
InvalidateData();
if (this.noAutoSizeCount > 0)
{
return;
}
// Autosize rows if needed
if ((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
AdjustShrinkingRows(this.autoSizeRowsMode, false /*fixedWidth*/, true /*internalAutosizing*/);
}
// Auto size columms also if needed
AutoResizeAllVisibleColumnsInternal(DataGridViewAutoSizeColumnCriteriaInternal.AllRows |
DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows,
true /*fixedHeight*/);
bool fixedRowHeadersWidth = this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.EnableResizing ||
this.rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.DisableResizing;
// Auto size column headers
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(fixedRowHeadersWidth, true /*fixedColumnsWidth*/);
}
// Auto size row headers
if (!fixedRowHeadersWidth)
{
AutoResizeRowHeadersWidth(this.rowHeadersWidthSizeMode, true /*fixedColumnHeadersHeight*/, true /*fixedRowsHeight*/);
}
// Second round of rows autosizing
if ((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
// Second round of column headers autosizing
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize && !fixedRowHeadersWidth)
{
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnsWidth*/);
}
}
internal void OnRowsRemovedInternal(int rowIndex, int rowCount)
{
OnRowsRemoved(new DataGridViewRowsRemovedEventArgs(rowIndex, rowCount));
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowsRemoved"]/*' />
protected virtual void OnRowsRemoved(DataGridViewRowsRemovedEventArgs e)
{
DataGridViewRowsRemovedEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWSREMOVED] as DataGridViewRowsRemovedEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowStateChanged"]/*' />
protected virtual void OnRowStateChanged(int rowIndex, DataGridViewRowStateChangedEventArgs e)
{
Debug.Assert(rowIndex >= -1);
// If row.Frozen changed, we need to update the vertical scroll bar
// A hidden row may become visible and vice-versa, we'd better repaint the whole control
DataGridViewRow dataGridViewRow = e.Row;
DataGridViewElementStates newState = DataGridViewElementStates.None;
bool rowVisible = false;
if (rowIndex >= 0)
{
newState = this.Rows.GetRowState(rowIndex);
rowVisible = ((newState & DataGridViewElementStates.Visible) != 0);
}
switch (e.StateChanged)
{
// At this point we assume that only the Selected state has an influence on the rendering of the row.
// If there is a customer scenario where another state has an influence, the dev will have to invalidate the row by hand.
// case DataGridViewElementStates.ReadOnly:
// case DataGridViewElementStates.Resizable:
case DataGridViewElementStates.Selected:
if (rowVisible && this.inBulkPaintCount == 0)
{
InvalidateRowPrivate(rowIndex);
}
break;
case DataGridViewElementStates.Frozen:
if (rowVisible)
{
if ((newState & DataGridViewElementStates.Frozen) == 0)
{
// row was unfrozen - make it the first visible scrolling row if there is room
FirstVisibleScrollingRowTempted(rowIndex);
}
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, true /*repositionEditingControl*/);
Invalidate();
}
break;
case DataGridViewElementStates.Visible:
{
if (!rowVisible && (newState & DataGridViewElementStates.Displayed) != 0)
{
// Displayed row becomes invisible. Turns off the Displayed state.
this.Rows.SetRowState(rowIndex, DataGridViewElementStates.Displayed, false);
}
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, true /*invalidInAdjustFillingColumns*/, true /*repositionEditingControl*/);
Invalidate();
bool rowDisplayed = (this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Displayed) != 0;
DataGridViewAutoSizeRowsModeInternal autoSizeRowsModeInternal = (DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode;
bool autoSizeRow = false;
if (autoSizeRowsModeInternal != DataGridViewAutoSizeRowsModeInternal.None)
{
int height = dataGridViewRow.ThicknessInternal;
if (rowVisible)
{
// Cache row's height before potential autosizing occurs
// Valid operation even for shared rows
dataGridViewRow.CachedThickness = height;
if (!((autoSizeRowsModeInternal & DataGridViewAutoSizeRowsModeInternal.DisplayedRows) != 0 && !rowDisplayed))
{
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), false /*fixedWidth*/, true /*internalAutosizing*/);
autoSizeRow = true;
}
}
else if (height != dataGridViewRow.CachedThickness)
{
// Rows that are made invisible in the collection take their non-autosized height
// Not calling OnRowHeightInfoPushed(...) because rows are autosized
// Make sure the affected row is unshared
if (dataGridViewRow.Index == -1)
{
dataGridViewRow = this.Rows[rowIndex];
}
dataGridViewRow.ThicknessInternal = Math.Max(dataGridViewRow.MinimumHeight, dataGridViewRow.CachedThickness);
}
}
// Auto size columms also if needed
DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaFilter = DataGridViewAutoSizeColumnCriteriaInternal.AllRows;
if (rowDisplayed)
{
autoSizeColumnCriteriaFilter |= DataGridViewAutoSizeColumnCriteriaInternal.DisplayedRows;
}
if (rowVisible && this.Rows.GetRowCount(DataGridViewElementStates.Visible) > 1)
{
// Columns can only expand, and not collapse.
AdjustExpandingColumns(autoSizeColumnCriteriaFilter, rowIndex);
}
else
{
AutoResizeAllVisibleColumnsInternal(autoSizeColumnCriteriaFilter, true /*fixedHeight*/);
}
if (autoSizeRow)
{
// Second round of row autosizing
AutoResizeRowInternal(rowIndex, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), true /*fixedWidth*/, true /*internalAutosizing*/);
}
break;
}
}
DataGridViewRowStateChangedEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWSTATECHANGED] as DataGridViewRowStateChangedEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
if (e.StateChanged == DataGridViewElementStates.ReadOnly &&
rowIndex == this.ptCurrentCell.Y &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange])
{
VerifyImeRestrictedModeChanged();
if ((newState & DataGridViewElementStates.ReadOnly) == 0 &&
!this.ReadOnly &&
!this.Columns[this.ptCurrentCell.X].ReadOnly &&
ColumnEditable(this.ptCurrentCell.X) &&
!this.IsCurrentCellInEditMode &&
(this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null)))
{
// Current row becomes read/write. Enter editing mode.
BeginEditInternal(true /*selectAll*/);
}
}
}
internal void OnRowUnshared(DataGridViewRow dataGridViewRow)
{
if (-1 != this.ptCurrentCell.X && dataGridViewRow.Index == this.ptCurrentCell.Y && this.editingControl != null)
{
this.CurrentCellInternal.CacheEditingControl();
}
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs(dataGridViewRow);
OnRowUnshared(dgvre);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowUnshared"]/*' />
protected virtual void OnRowUnshared(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWUNSHARED] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private bool OnRowValidating(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex)
{
DataGridViewCellCancelEventArgs dgvcce = new DataGridViewCellCancelEventArgs(columnIndex, rowIndex);
OnRowValidating(dgvcce);
if (!dgvcce.Cancel)
{
if (this.dataConnection != null &&
this.dataConnection.InterestedInRowEvents &&
!this.dataConnection.PositionChangingOutsideDataGridView &&
!this.dataConnection.ListWasReset)
{
this.dataConnection.OnRowValidating(dgvcce);
}
}
if (dataGridViewCell != null && rowIndex < this.Rows.Count && columnIndex < this.Columns.Count)
{
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
return dgvcce.Cancel;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowValidating"]/*' />
protected virtual void OnRowValidating(DataGridViewCellCancelEventArgs e)
{
try
{
this.noDimensionChangeCount++;
DataGridViewCellCancelEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWVALIDATING] as DataGridViewCellCancelEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
}
}
private void OnRowValidated(ref DataGridViewCell dataGridViewCell, int columnIndex, int rowIndex)
{
this.IsCurrentRowDirtyInternal = false;
this.dataGridViewState1[DATAGRIDVIEWSTATE1_newRowCreatedByEditing] = false;
if (rowIndex == this.newRowIndex)
{
// Stop displaying the default cell values on the 'new row'.
InvalidateRowPrivate(rowIndex);
}
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(columnIndex, rowIndex);
OnRowValidated(dgvce);
if (dataGridViewCell != null)
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
dataGridViewCell = null;
}
else
{
Debug.Assert(rowIndex < this.Rows.Count && columnIndex < this.Columns.Count);
dataGridViewCell = this.Rows.SharedRow(rowIndex).Cells[columnIndex];
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnRowValidated"]/*' />
protected virtual void OnRowValidated(DataGridViewCellEventArgs e)
{
try
{
this.noDimensionChangeCount++;
DataGridViewCellEventHandler eh = this.Events[EVENT_DATAGRIDVIEWROWVALIDATED] as DataGridViewCellEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
CorrectFocus(true /*onlyIfGridHasFocus*/);
}
}
finally
{
this.noDimensionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
}
}
private void RefreshByCurrentPos(int oldValue, int newValue)
{
Point pt = PointToScreen(Location);
int step = newValue - oldValue;
// horizontal scrool left
if (pt.X < 0 && step < 0)
{
Invalidate(new Rectangle(new Point(-pt.X, ColumnHeadersHeight),
new Size(-step, ClientSize.Height)));
}
pt.X += Width;
pt.Y += Height;
Rectangle rect = Screen.GetBounds(pt);
// horizontal scrool right
if (pt.X > rect.Right && step > 0)
{
Invalidate(new Rectangle(new Point(ClientSize.Width - (pt.X - rect.Right) - step, ColumnHeadersHeight),
new Size(step, ClientSize.Height)));
}
// vertical scrool up
if (pt.Y < 0 && step < 0)
{
Invalidate(new Rectangle(new Point(0, -pt.Y),
new Size(-step, ClientSize.Width)));
}
// vertical scrool down
if (pt.Y > rect.Bottom && step > 0)
{
Invalidate(new Rectangle(new Point(0, ColumnHeadersHeight),
new Size(ClientSize.Width, ClientSize.Height - (pt.Y - rect.Bottom) - step)));
}
}
private void OnScroll(ScrollEventType scrollEventType, int oldValue, int newValue, ScrollOrientation orientation)
{
ScrollEventArgs se = new ScrollEventArgs(scrollEventType, oldValue, newValue, orientation);
OnScroll(se);
RefreshByCurrentPos(oldValue, newValue);
if (this.Focused && this.IsGridFocusRectangleEnabled())
{
InvalidateGridFocusOnScroll(newValue - oldValue, orientation);
}
if (ScrollOrientation.VerticalScroll == orientation)
{
if (se.NewValue != newValue)
{
try
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_stopRaisingVerticalScroll] = true;
int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
int rowIndexPrevious = rowIndex;
newValue = se.NewValue;
while (rowIndex != -1 && newValue > 0)
{
rowIndexPrevious = rowIndex;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
newValue--;
}
if (rowIndex != -1)
{
rowIndexPrevious = rowIndex;
}
if (rowIndexPrevious != -1)
{
this.FirstDisplayedScrollingRowIndex = rowIndexPrevious;
}
}
finally
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_stopRaisingVerticalScroll] = false;
}
}
}
else
{
if (se.NewValue != newValue)
{
try
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_stopRaisingHorizontalScroll] = true;
this.HorizontalOffset = se.NewValue;
}
finally
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_stopRaisingHorizontalScroll] = false;
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnScroll"]/*' />
protected virtual void OnScroll(ScrollEventArgs e)
{
ScrollEventHandler eh = this.Events[EVENT_DATAGRIDVIEWSCROLL] as ScrollEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnSelectionChanged"]/*' />
protected virtual void OnSelectionChanged(EventArgs e)
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_raiseSelectionChanged] = false;
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWSELECTIONCHANGED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal bool OnSortCompare(DataGridViewColumn dataGridViewSortedColumn, object value1, object value2, int rowIndex1, int rowIndex2, out int sortResult)
{
DataGridViewSortCompareEventArgs dgvsce = new DataGridViewSortCompareEventArgs(dataGridViewSortedColumn, value1, value2, rowIndex1, rowIndex2);
OnSortCompare(dgvsce);
sortResult = dgvsce.SortResult;
return dgvsce.Handled;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnSortCompare"]/*' />
protected virtual void OnSortCompare(DataGridViewSortCompareEventArgs e)
{
DataGridViewSortCompareEventHandler eh = this.Events[EVENT_DATAGRIDVIEWSORTCOMPARE] as DataGridViewSortCompareEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnSorted"]/*' />
protected virtual void OnSorted(EventArgs e)
{
EventHandler eh = this.Events[EVENT_DATAGRIDVIEWSORTED] as EventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
internal void OnSortGlyphDirectionChanged(DataGridViewColumnHeaderCell dataGridViewColumnHeaderCell)
{
Debug.Assert(dataGridViewColumnHeaderCell != null);
if (dataGridViewColumnHeaderCell.OwningColumn == this.SortedColumn)
{
if (dataGridViewColumnHeaderCell.SortGlyphDirection == SortOrder.None)
{
this.sortedColumn = null;
DataGridViewColumn dataGridViewColumn = dataGridViewColumnHeaderCell.OwningColumn;
if (dataGridViewColumn.IsDataBound)
{
// If the column whose SortGlyphChanges is the sorted column and it is also the dataBound column
// then see if there is another dataBound column which has the same property name as the sorted column.
// If so, then make that dataGridViewColumn the sorted column in the data grid view.
for (int i = 0; i < this.Columns.Count; i ++)
{
if (dataGridViewColumn != this.Columns[i] &&
this.Columns[i].SortMode != DataGridViewColumnSortMode.NotSortable &&
String.Compare(dataGridViewColumn.DataPropertyName,
this.Columns[i].DataPropertyName,
true /*ignoreCase*/,
CultureInfo.InvariantCulture) == 0)
{
Debug.Assert(this.Columns[i].IsDataBound, "two columns w/ the same DataPropertyName should be DataBound at the same time");
this.sortedColumn = this.Columns[i];
break;
}
}
}
}
this.sortOrder = this.sortedColumn != null ? this.sortedColumn.HeaderCell.SortGlyphDirection : SortOrder.None;
}
InvalidateCellPrivate(dataGridViewColumnHeaderCell);
}
private void OnTopLeftHeaderMouseDown()
{
if (this.MultiSelect)
{
SelectAll();
if (-1 != this.ptCurrentCell.X)
{
// Potentially have to give focus back to the current edited cell.
bool success = SetCurrentCellAddressCore(this.ptCurrentCell.X, this.ptCurrentCell.Y,
false /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/);
Debug.Assert(success);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnUserAddedRow"]/*' />
protected virtual void OnUserAddedRow(DataGridViewRowEventArgs e)
{
if (e.Row.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_RowDoesNotBelongToDataGridView), "e.Row");
}
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWUSERADDEDROW] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnUserDeletedRow"]/*' />
protected virtual void OnUserDeletedRow(DataGridViewRowEventArgs e)
{
DataGridViewRowEventHandler eh = this.Events[EVENT_DATAGRIDVIEWUSERDELETEDROW] as DataGridViewRowEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnUserDeletingRow"]/*' />
protected virtual void OnUserDeletingRow(DataGridViewRowCancelEventArgs e)
{
DataGridViewRowCancelEventHandler eh = this.Events[EVENT_DATAGRIDVIEWUSERDELETINGROW] as DataGridViewRowCancelEventHandler;
if (eh != null && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose] && !this.IsDisposed)
{
eh(this, e);
}
}
private void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
if (e.Category == UserPreferenceCategory.Color ||
e.Category == UserPreferenceCategory.Locale ||
e.Category == UserPreferenceCategory.General ||
e.Category == UserPreferenceCategory.Window ||
e.Category == UserPreferenceCategory.VisualStyle)
{
OnGlobalAutoSize();
if (e.Category == UserPreferenceCategory.Window)
{
this.cachedEditingControl = null;
if (this.editingControl != null)
{
// The editing control may not adapt well to the new system rendering,
// so instead of caching it into the this.cachedEditingControl variable
// next time editing mode is exited, simply discard the control.
this.dataGridViewState2[DATAGRIDVIEWSTATE2_discardEditingControl] = true;
}
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, false /*invalidInAdjustFillingColumns*/, true /*repositionEditingControl*/);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.OnValidating"]/*' />
protected override void OnValidating(CancelEventArgs e)
{
// VSWhidbey 481170. Avoid Cell/Row Validation events when the grid or its editing control gets the focus
if (!this.BecomingActiveControl && (this.editingControl == null || !this.editingControl.BecomingActiveControl))
{
if (!this.dataGridViewState1[DATAGRIDVIEWSTATE1_leavingWithTabKey])
{
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.LeaveControl,
DataGridViewValidateCellInternal.Always,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
false /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell unused here*/))
{
e.Cancel = true;
return;
}
}
if (this.ptCurrentCell.X >= 0)
{
DataGridViewCell dataGridViewCellTmp = null;
if (OnRowValidating(ref dataGridViewCellTmp, this.ptCurrentCell.X, this.ptCurrentCell.Y))
{
// Row validation was cancelled
e.Cancel = true;
return;
}
if (this.ptCurrentCell.X == -1)
{
return;
}
OnRowValidated(ref dataGridViewCellTmp, this.ptCurrentCell.X, this.ptCurrentCell.Y);
// Row validation was not cancelled, but does operation need to be re-evaluated.
if (this.DataSource != null &&
this.ptCurrentCell.X >= 0 &&
this.AllowUserToAddRowsInternal &&
this.newRowIndex == this.ptCurrentCell.Y)
{
// Current cell needs to be moved to the row just above the 'new row' if possible.
int rowIndex = this.Rows.GetPreviousRow(this.ptCurrentCell.Y, DataGridViewElementStates.Visible);
if (rowIndex > -1)
{
bool success = SetAndSelectCurrentCellAddress(this.ptCurrentCell.X, rowIndex,
true /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/,
false /*clearSelection*/,
false /*forceCurrentCellSelection*/);
Debug.Assert(success);
}
else
{
bool success = SetCurrentCellAddressCore(-1, -1,
true /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/);
Debug.Assert(success);
}
}
}
}
base.OnValidating(e);
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
OnVisibleChangedPrivate();
}
private void OnVisibleChangedPrivate()
{
// Debug.Assert(!this.displayedBandsInfo.Dirty); Not valid because EnsureDirtyState can potentially be called
// for example when RowHeadersVisible is changed while the control is invisible.
int rowIndexTmp;
if (this.Visible)
{
// Make sure all displayed bands get the Displayed state: 1 & 2 for rows
// 1. Make sure all displayed frozen rows have their Displayed state set to true
int numDisplayedFrozenRows = this.displayedBandsInfo.NumDisplayedFrozenRows;
if (numDisplayedFrozenRows > 0)
{
rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (numDisplayedFrozenRows > 0)
{
Debug.Assert(rowIndexTmp != -1);
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0)
{
#if DEBUG
int numDisplayedFrozenRowsDbg = numDisplayedFrozenRows;
while (numDisplayedFrozenRowsDbg > 0)
{
Debug.Assert(rowIndexTmp != -1);
Debug.Assert((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
numDisplayedFrozenRowsDbg--;
}
#endif
return; // rows' Displayed states are already up-to-date. OnHandleCreated already did the job.
}
else
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, true);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
numDisplayedFrozenRows--;
}
}
}
// 2. Make sure all displayed scrolling rows have their Displayed state set to true
rowIndexTmp = this.displayedBandsInfo.FirstDisplayedScrollingRow;
if (rowIndexTmp > -1)
{
Debug.Assert((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Visible) != 0);
int numDisplayedScrollingRows = this.displayedBandsInfo.NumDisplayedScrollingRows;
Debug.Assert(numDisplayedScrollingRows > 0);
while (numDisplayedScrollingRows > 0)
{
Debug.Assert(rowIndexTmp != -1);
if ((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0)
{
#if DEBUG
int numDisplayedScrollingRowsDbg = numDisplayedScrollingRows;
while (numDisplayedScrollingRowsDbg > 0)
{
Debug.Assert(rowIndexTmp != -1);
Debug.Assert((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) != 0);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
numDisplayedScrollingRowsDbg--;
}
#endif
return; // rows' Displayed states are already up-to-date. OnHandleCreated already did the job.
}
else
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, true);
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
numDisplayedScrollingRows--;
}
}
}
}
else
{
// Make sure all displayed bands lose the Displayed state
UpdateRowsDisplayedState(false /*displayed*/);
}
UpdateColumnsDisplayedState(this.Visible /*displayed*/);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.PaintBackground"]/*' />
protected virtual void PaintBackground(Graphics graphics, Rectangle clipBounds, Rectangle gridBounds)
{
// Paint potential block below rows
Rectangle rcBelowRows = gridBounds;
// Fix Dev10 Bug473771 - Remaining cell images on DataGridView
int visibleRowsHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Displayed);
if (this.layout.ColumnHeadersVisible)
{
rcBelowRows.Y += this.layout.ColumnHeaders.Height;
rcBelowRows.Height -= this.layout.ColumnHeaders.Height;
}
else if (this.SingleHorizontalBorderAdded && visibleRowsHeight > 0)
{
rcBelowRows.Y++;
rcBelowRows.Height--;
}
rcBelowRows.Y += visibleRowsHeight;
rcBelowRows.Height -= visibleRowsHeight;
if (rcBelowRows.Width > 0 && rcBelowRows.Height > 0)
{
graphics.FillRectangle(this.backgroundBrush, rcBelowRows);
}
// Paint potential block next to column headers and rows
// Fix Dev10 Bug473771 - Remaining cell images on DataGridView
int visibleColumnsWidth = this.Columns.GetColumnsWidth(DataGridViewElementStates.Displayed);
Rectangle rcNextRows = gridBounds;
if (this.Columns.Count > 0)
{
if (this.layout.RowHeadersVisible)
{
if (!this.RightToLeftInternal)
{
rcNextRows.X += this.layout.RowHeaders.Width;
}
rcNextRows.Width -= this.layout.RowHeaders.Width;
}
else if (this.SingleVerticalBorderAdded && visibleColumnsWidth > 0)
{
if (!this.RightToLeftInternal)
{
rcNextRows.X++;
}
rcNextRows.Width--;
}
}
int rowsWidth = visibleColumnsWidth - this.horizontalOffset;
if (!this.RightToLeftInternal)
{
rcNextRows.X += rowsWidth;
}
rcNextRows.Width -= rowsWidth;
if (rcBelowRows.Height > 0)
{
rcNextRows.Height = gridBounds.Height - rcBelowRows.Height;
}
if (rcNextRows.Width > 0 && rcNextRows.Height > 0)
{
graphics.FillRectangle(this.backgroundBrush, rcNextRows);
}
}
private void PaintBorder(Graphics g, Rectangle clipRect, Rectangle bounds)
{
Debug.Assert(bounds.Left == 0);
Debug.Assert(bounds.Top == 0);
if (this.BorderStyle == BorderStyle.None)
{
return;
}
bool paintingNeeded = false;
int borderWidth = this.BorderWidth;
// Does the clipRect intersect with the top edge?
Rectangle edge = new Rectangle(0, 0, bounds.Width, borderWidth);
paintingNeeded = clipRect.IntersectsWith(edge);
if (!paintingNeeded)
{
// Does the clipRect intersect with the bottom edge?
edge.Y = bounds.Height - borderWidth;
paintingNeeded = clipRect.IntersectsWith(edge);
if (!paintingNeeded)
{
// Does the clipRect intersect with the left edge?
edge.Y = 0;
edge.Height = bounds.Height;
edge.Width = borderWidth;
paintingNeeded = clipRect.IntersectsWith(edge);
if (!paintingNeeded)
{
// Does the clipRect intersect with the right edge?
edge.X = bounds.Width - borderWidth;
paintingNeeded = clipRect.IntersectsWith(edge);
}
}
}
if (paintingNeeded)
{
if (this.BorderStyle == BorderStyle.Fixed3D)
{
if (Application.RenderWithVisualStyles)
{
Pen pen = GetCachedPen(VisualStyleInformation.TextControlBorder);
g.DrawRectangle(pen, new Rectangle(0, 0, bounds.Width - 1, bounds.Height - 1));
}
else
{
ControlPaint.DrawBorder3D(g, bounds, Border3DStyle.Sunken);
}
}
else if (this.BorderStyle == BorderStyle.FixedSingle)
{
Pen pen = GetCachedPen(SystemColors.ControlText);
g.DrawRectangle(pen, new Rectangle(0, 0, bounds.Width - 1, bounds.Height - 1));
}
else
{
Debug.Fail("DataGridView.PaintBorder - Unexpected BorderStyle value.");
}
}
}
private void PaintColumnHeaders(Graphics g, Rectangle clipBounds, bool singleBorderAdded)
{
if (g.IsVisible(this.layout.ColumnHeaders))
{
Rectangle bandBounds, cellBounds;
bandBounds = cellBounds = this.layout.ColumnHeaders;
bandBounds.Height = cellBounds.Height = this.columnHeadersHeight;
int cx = 0;
bool isFirstDisplayedColumn = true, isLastVisibleColumn = false;
DataGridViewCell cell;
DataGridViewCellStyle inheritedCellStyle = new DataGridViewCellStyle();
DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder = new DataGridViewAdvancedBorderStyle(), dgvabsEffective;
DataGridViewColumn dataGridViewColumnNext = null;
// first paint the visible frozen columns
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (dataGridViewColumn != null)
{
cell = dataGridViewColumn.HeaderCell;
cellBounds.Width = dataGridViewColumn.Thickness;
if (singleBorderAdded && isFirstDisplayedColumn)
{
cellBounds.Width++;
}
Debug.Assert(cellBounds.Width > 0);
if (this.RightToLeftInternal)
{
cellBounds.X = bandBounds.Right - cx - cellBounds.Width;
}
else
{
cellBounds.X = bandBounds.X + cx;
}
BuildInheritedColumnHeaderCellStyle(inheritedCellStyle, cell);
dataGridViewColumnNext = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen,
DataGridViewElementStates.None);
if (dataGridViewColumnNext == null)
{
isLastVisibleColumn = (this.displayedBandsInfo.FirstDisplayedScrollingCol < 0);
}
dgvabsEffective = AdjustColumnHeaderBorderStyle(this.AdvancedColumnHeadersBorderStyle, dataGridViewAdvancedBorderStylePlaceholder,
isFirstDisplayedColumn, isLastVisibleColumn);
// Microsoft: should paintSelectionBackground be dev-settable?
cell.PaintWork(g,
clipBounds,
cellBounds,
-1,
dataGridViewColumn.State,
inheritedCellStyle,
dgvabsEffective,
DataGridViewPaintParts.Background | DataGridViewPaintParts.Border | DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.SelectionBackground);
cx += cellBounds.Width;
if (cx >= bandBounds.Width)
{
break;
}
dataGridViewColumn = dataGridViewColumnNext;
isFirstDisplayedColumn = false;
}
// then paint the visible scrolling ones
Rectangle scrollingBounds = bandBounds;
if (!this.RightToLeftInternal)
{
scrollingBounds.X -= this.negOffset;
}
scrollingBounds.Width += this.negOffset;
if (this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0 && cx < scrollingBounds.Width)
{
Region clipRegion = null;
if (this.negOffset > 0)
{
clipRegion = g.Clip;
Rectangle rowRect = bandBounds;
if (!this.RightToLeftInternal)
{
rowRect.X += cx;
}
rowRect.Width -= cx;
g.SetClip(rowRect);
}
dataGridViewColumn = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
while (dataGridViewColumn != null)
{
Debug.Assert(dataGridViewColumn.Visible && !dataGridViewColumn.Frozen);
cell = dataGridViewColumn.HeaderCell;
cellBounds.Width = dataGridViewColumn.Thickness;
if (singleBorderAdded && isFirstDisplayedColumn)
{
cellBounds.Width++;
}
Debug.Assert(cellBounds.Width > 0);
if (this.RightToLeftInternal)
{
cellBounds.X = scrollingBounds.Right - cx - cellBounds.Width;
}
else
{
cellBounds.X = scrollingBounds.X + cx;
}
BuildInheritedColumnHeaderCellStyle(inheritedCellStyle, cell);
dataGridViewColumnNext = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
isLastVisibleColumn = (dataGridViewColumnNext == null);
dgvabsEffective = AdjustColumnHeaderBorderStyle(this.AdvancedColumnHeadersBorderStyle, dataGridViewAdvancedBorderStylePlaceholder,
isFirstDisplayedColumn, isLastVisibleColumn);
cell.PaintWork(g,
clipBounds,
cellBounds,
-1,
dataGridViewColumn.State,
inheritedCellStyle,
dgvabsEffective,
DataGridViewPaintParts.Background | DataGridViewPaintParts.Border | DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.SelectionBackground);
cx += cellBounds.Width;
if (cx >= scrollingBounds.Width)
{
break;
}
dataGridViewColumn = dataGridViewColumnNext;
isFirstDisplayedColumn = false;
}
if (this.negOffset > 0)
{
Debug.Assert(clipRegion != null);
g.Clip = clipRegion;
clipRegion.Dispose();
}
}
}
}
private void PaintGrid(Graphics g,
Rectangle gridBounds,
Rectangle clipRect,
bool singleVerticalBorderAdded,
bool singleHorizontalBorderAdded)
{
Rectangle rc = gridBounds;
if (this.layout.TopLeftHeader.Width > 0 &&
(clipRect.IntersectsWith(this.layout.TopLeftHeader) || this.lastHeaderShadow != -1))
{
if (this.Columns.Count > 0 || this.Rows.Count > 0)
{
using (Region clipRegion = g.Clip)
{
g.SetClip(this.layout.TopLeftHeader);
PaintTopLeftHeaderCell(g);
g.Clip = clipRegion;
}
}
}
if (this.layout.ColumnHeadersVisible)
{
Rectangle columnHeadersClip = new Rectangle();
columnHeadersClip = this.layout.ColumnHeaders;
if (singleVerticalBorderAdded)
{
columnHeadersClip.Width++;
}
if (clipRect.IntersectsWith(columnHeadersClip) || this.lastHeaderShadow != -1)
{
using (Region clipRegion = g.Clip)
{
g.SetClip(columnHeadersClip);
PaintColumnHeaders(g, columnHeadersClip, singleVerticalBorderAdded);
g.Clip = clipRegion;
}
}
int columnHeadersHeight = this.layout.ColumnHeaders.Height;
rc.Y += columnHeadersHeight;
rc.Height -= columnHeadersHeight;
if (this.lastHeaderShadow != -1)
{
DrawColHeaderShadow(g, this.lastHeaderShadow);
}
}
if (rc.Height > 0)
{
PaintRows(g, rc, clipRect, /*singleVerticalBorderAdded, */ singleHorizontalBorderAdded);
}
if (this.currentRowSplitBar != -1)
{
Debug.Assert(this.dataGridViewOper[DATAGRIDVIEWOPER_trackColHeadersResize] || this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowResize]);
DrawRowSplitBar(this.currentRowSplitBar);
}
else if (this.currentColSplitBar != -1)
{
Debug.Assert(this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowHeadersResize] ||
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColResize] ||
this.dataGridViewOper[DATAGRIDVIEWOPER_trackKeyboardColResize]);
DrawColSplitBar(this.currentColSplitBar);
}
}
private void PaintRows(Graphics g,
Rectangle boundingRect,
Rectangle clipRect,
/*bool singleVerticalBorderAdded,*/
bool singleHorizontalBorderAdded)
{
int cy = 0;
Rectangle rowBounds;
DataGridViewRow dataGridViewRow;
bool isFirstDisplayedRow = true;
int indexTmp, indexTmpNext;
// paint visible none-scrolling rows
indexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (indexTmp != -1)
{
rowBounds = boundingRect;
// Dev 10 Bug #434494 - DataGridView AutoSizeRowsMode does not work properly after column sort
// Should unshared the row and set the thickness to a perfect value
// every time user scroll to display the specific row.
DataGridViewAutoSizeRowsModeInternal autoSizeRowsModeInternal = (DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode;
// Auto size row if needed
if (autoSizeRowsModeInternal != DataGridViewAutoSizeRowsModeInternal.None)
{
// this call may unshare the row.
int rowHeight = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
this.Rows.SharedRow(indexTmp).CachedThickness = rowHeight;
AutoResizeRowInternal(indexTmp, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), false /*fixedWidth*/, true /*internalAutosizing*/);
}
rowBounds.Height = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
if (isFirstDisplayedRow && singleHorizontalBorderAdded)
{
rowBounds.Height++;
}
rowBounds.Y = boundingRect.Y + cy;
indexTmpNext = this.Rows.GetNextRow(indexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
if (clipRect.IntersectsWith(rowBounds))
{
dataGridViewRow = this.Rows.SharedRow(indexTmp);
dataGridViewRow.Paint(g,
clipRect,
rowBounds,
indexTmp,
this.Rows.GetRowState(indexTmp),
isFirstDisplayedRow,
(indexTmpNext == -1) && (this.displayedBandsInfo.FirstDisplayedScrollingRow == -1));
}
cy += rowBounds.Height;
if (cy >= boundingRect.Height)
{
break;
}
indexTmp = indexTmpNext;
isFirstDisplayedRow = false;
}
// paint scrolling rows
if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0 && cy < boundingRect.Height)
{
indexTmp = this.displayedBandsInfo.FirstDisplayedScrollingRow;
Debug.Assert((this.Rows.GetRowState(indexTmp) & DataGridViewElementStates.Frozen) == 0);
Debug.Assert((this.Rows.GetRowState(indexTmp) & DataGridViewElementStates.Visible) != 0);
while (indexTmp != -1)
{
rowBounds = boundingRect;
// Dev 10 Bug #434494 - DataGridView AutoSizeRowsMode does not work properly after column sort
// Should unshared the row and set the thickness to a perfect value
// every time user scroll to display the specific row.
DataGridViewAutoSizeRowsModeInternal autoSizeRowsModeInternal = (DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode;
// Auto size row if needed
if (autoSizeRowsModeInternal != DataGridViewAutoSizeRowsModeInternal.None)
{
// this call may unshare the row.
int rowHeight = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
this.Rows.SharedRow(indexTmp).CachedThickness = rowHeight;
AutoResizeRowInternal(indexTmp, MapAutoSizeRowsModeToRowMode(this.autoSizeRowsMode), false /*fixedWidth*/, true /*internalAutosizing*/);
}
rowBounds.Height = this.Rows.SharedRow(indexTmp).GetHeight(indexTmp);
if (isFirstDisplayedRow && singleHorizontalBorderAdded)
{
rowBounds.Height++;
}
rowBounds.Y = boundingRect.Y + cy;
indexTmpNext = this.Rows.GetNextRow(indexTmp, DataGridViewElementStates.Visible);
if (clipRect.IntersectsWith(rowBounds))
{
dataGridViewRow = this.Rows.SharedRow(indexTmp);
dataGridViewRow.Paint(g,
clipRect,
rowBounds,
indexTmp,
this.Rows.GetRowState(indexTmp),
isFirstDisplayedRow,
indexTmpNext == -1);
}
cy += rowBounds.Height;
if (cy >= boundingRect.Height)
{
break;
}
indexTmp = indexTmpNext;
isFirstDisplayedRow = false;
}
}
}
private void PaintTopLeftHeaderCell(Graphics g)
{
if (g.IsVisible(this.layout.TopLeftHeader))
{
DataGridViewCell cell = this.TopLeftHeaderCell;
DataGridViewCellStyle inheritedCellStyle = new DataGridViewCellStyle();
BuildInheritedColumnHeaderCellStyle(inheritedCellStyle, cell);
Rectangle cellBounds = this.layout.TopLeftHeader;
cellBounds.Width = this.rowHeadersWidth;
cellBounds.Height = this.columnHeadersHeight;
// Microsoft: Should paintSelectionBackground be dev-settable?
cell.PaintWork(g,
this.layout.TopLeftHeader,
cellBounds,
-1,
cell.State,
inheritedCellStyle,
this.AdjustedTopLeftHeaderBorderStyle,
DataGridViewPaintParts.Background | DataGridViewPaintParts.Border | DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.SelectionBackground);
}
}
private void PerformLayoutPrivate(bool useRowShortcut,
bool computeVisibleRows,
bool invalidInAdjustFillingColumns,
bool repositionEditingControl)
{
this.inPerformLayoutCount++;
try
{
if (invalidInAdjustFillingColumns && this.InAdjustFillingColumns)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotAlterAutoFillColumnParameter));
}
if (this.IsHandleCreated)
{
bool columnsAdjusted = false;
if (useRowShortcut)
{
ComputeLayoutShortcut(computeVisibleRows);
}
else
{
columnsAdjusted = ComputeLayout();
}
FlushDisplayedChanged();
if (columnsAdjusted && this.inPerformLayoutCount < 3)
{
// Some columns were auto-filled, the rows and column headers may need to be autosized.
if ((((DataGridViewAutoSizeRowsModeInternal)this.autoSizeRowsMode) & DataGridViewAutoSizeRowsModeInternal.AllColumns) != 0)
{
AdjustShrinkingRows(this.autoSizeRowsMode, true /*fixedWidth*/, true /*internalAutosizing*/);
}
if (this.ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
AutoResizeColumnHeadersHeight(true /*fixedRowHeadersWidth*/, true /*fixedColumnWidth*/);
}
}
if (repositionEditingControl && this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, false /*setSize*/, false /*setFocus*/);
}
}
else
{
this.displayedBandsInfo.FirstDisplayedFrozenCol = -1;
this.displayedBandsInfo.FirstDisplayedFrozenRow = -1;
this.displayedBandsInfo.FirstDisplayedScrollingRow = -1;
this.displayedBandsInfo.FirstDisplayedScrollingCol = -1;
this.displayedBandsInfo.NumDisplayedFrozenRows = 0;
this.displayedBandsInfo.NumDisplayedFrozenCols = 0;
this.displayedBandsInfo.NumDisplayedScrollingRows = 0;
this.displayedBandsInfo.NumDisplayedScrollingCols = 0;
this.displayedBandsInfo.NumTotallyDisplayedFrozenRows = 0;
this.displayedBandsInfo.NumTotallyDisplayedScrollingRows = 0;
this.displayedBandsInfo.LastDisplayedScrollingRow = -1;
this.displayedBandsInfo.LastTotallyDisplayedScrollingCol = -1;
if (this.layout != null)
{
this.layout.dirty = true;
}
}
}
finally
{
this.inPerformLayoutCount--;
Debug.Assert(this.inPerformLayoutCount >= 0);
}
}
[
SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops") // Illegitimate report.
]
private void PopulateNewRowWithDefaultValues()
{
if (this.newRowIndex != -1)
{
DataGridViewRow newRow = this.Rows.SharedRow(this.newRowIndex);
DataGridViewCellCollection newRowCells = newRow.Cells;
foreach (DataGridViewCell dataGridViewCell in newRowCells)
{
if (dataGridViewCell.DefaultNewRowValue != null)
{
newRow = this.Rows[this.newRowIndex]; // unshare the 'new row'.
newRowCells = newRow.Cells;
break;
}
}
foreach (DataGridViewCell dataGridViewCell in newRowCells)
{
dataGridViewCell.SetValueInternal(this.newRowIndex, dataGridViewCell.DefaultNewRowValue);
}
}
}
private void PositionEditingControl(bool setLocation, bool setSize, bool setFocus)
{
Debug.Assert(this.editingControl != null);
if (!this.IsHandleCreated)
{
return;
}
#if DEBUG
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCell != null);
Debug.Assert(dataGridViewCell.ColumnIndex == this.ptCurrentCell.X);
Debug.Assert(dataGridViewCell.RowIndex == this.ptCurrentCell.Y || dataGridViewCell.RowIndex == -1);
#endif
Rectangle editingZone = this.layout.Data;
if (editingZone.Width == 0 || editingZone.Height == 0)
{
return;
}
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlChanging] = true;
try
{
int leftEdge = GetColumnXFromIndex(this.ptCurrentCell.X);
if (this.RightToLeftInternal)
{
leftEdge -= this.Columns[this.ptCurrentCell.X].Width-1;
}
Rectangle cellBounds = new Rectangle(leftEdge, GetRowYFromIndex(this.ptCurrentCell.Y),
this.Columns[this.ptCurrentCell.X].Width, this.Rows.SharedRow(this.ptCurrentCell.Y).GetHeight(this.ptCurrentCell.Y));
Rectangle cellClip = cellBounds;
// Need to clip the zones of the frozen columns and rows and headers.
if (!this.Columns[this.ptCurrentCell.X].Frozen)
{
int totalVisibleFrozenWidth = this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
if (!this.RightToLeftInternal)
{
editingZone.X += totalVisibleFrozenWidth;
}
editingZone.Width = Math.Max(0, editingZone.Width - totalVisibleFrozenWidth);
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Frozen) == 0)
{
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
editingZone.Y += totalVisibleFrozenHeight;
}
cellClip.Intersect(editingZone);
if (cellClip.Width == 0 || cellClip.Height == 0)
{
// we cannot simply make the control invisible because we want it to keep the focus.
// (and Control::CanFocus returns false if the control is not visible).
// So we place the editing control to the right of the DataGridView.
Debug.Assert(this.editingControl != null);
this.editingPanel.Location = new Point(this.Width + 1, 0);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlHidden] = true;
}
else
{
bool singleVerticalBorderAdded = this.SingleVerticalBorderAdded;
bool singleHorizontalBorderAdded = this.SingleHorizontalBorderAdded;
bool isFirstDisplayedColumn = this.FirstDisplayedColumnIndex == this.ptCurrentCell.X;
bool isFirstDisplayedRow = this.FirstDisplayedRowIndex == this.ptCurrentCell.Y;
if (singleVerticalBorderAdded && isFirstDisplayedColumn)
{
if (!this.RightToLeftInternal)
{
cellBounds.X--;
cellClip.X--;
}
cellBounds.Width++;
cellClip.Width++;
}
if (singleHorizontalBorderAdded && isFirstDisplayedRow)
{
cellBounds.Y--;
cellClip.Y--;
cellBounds.Height++;
cellClip.Height++;
}
this.CurrentCellInternal.PositionEditingControl(
setLocation || this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlHidden],
setSize || this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlHidden],
cellBounds, cellClip, this.InheritedEditingCellStyle,
singleVerticalBorderAdded, singleHorizontalBorderAdded,
isFirstDisplayedColumn, isFirstDisplayedRow);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlHidden] = false;
}
this.editingPanel.Visible = true;
if (setFocus)
{
CorrectFocus(false /*onlyIfGridHasFocus*/);
}
}
finally
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_editingControlChanging] = false;
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessAKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessAKey(Keys keyData)
{
if ((keyData & (Keys.Shift | Keys.Control | Keys.Alt)) == Keys.Control &&
this.MultiSelect)
{
SelectAll();
return true;
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessDeleteKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode),
SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters") // Derived controls may need keyData.
]
protected bool ProcessDeleteKey(Keys keyData)
{
if (this.AllowUserToDeleteRowsInternal)
{
if (this.editingControl != null)
{
// editing control gets a chance to handle the Delete key first
return false;
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
int remainingSelectedRows = 0;
try
{
this.selectedBandSnapshotIndexes = new DataGridViewIntLinkedList(this.selectedBandIndexes);
while (this.selectedBandSnapshotIndexes.Count > remainingSelectedRows)
{
int rowIndex = this.selectedBandSnapshotIndexes[remainingSelectedRows];
Debug.Assert(rowIndex >= 0);
if (rowIndex == this.newRowIndex || rowIndex >= this.Rows.Count)
{
remainingSelectedRows++;
}
else
{
DataGridViewRowCancelEventArgs dgvrce = new DataGridViewRowCancelEventArgs(this.Rows[rowIndex]);
OnUserDeletingRow(dgvrce);
if (!dgvrce.Cancel)
{
DataGridViewRow dataGridViewRow = this.Rows[rowIndex];
if (this.DataSource != null)
{
int dataGridRowsCount = this.Rows.Count;
#if DEBUG
int dataGridViewRowsCount = this.Rows.Count; // the number of rows in the dataGridView row collection not counting the AddNewRow
int rowCount = this.dataConnection.CurrencyManager.List.Count;
if (this.AllowUserToAddRowsInternal )
{
if (this.newRowIndex < rowCount)
{
// the user did not type inside the 'add new row'
Debug.Assert(rowCount == dataGridViewRowsCount, "out of sync in AddNewTransaction when the user did not type in the 'add new row'");
}
else
{
dataGridViewRowsCount --;
}
}
Debug.Assert(rowCount == dataGridViewRowsCount, "out of sync");
#endif
DataGridViewDataErrorEventArgs dgvdee = null;
try
{
this.DataConnection.DeleteRow(rowIndex);
}
catch (Exception exception)
{
if (ClientUtils.IsCriticalException(exception))
{
throw;
}
// this is tricky.
// the back-end threw an exception. At that stage, we did not delete the dataGridView row
// from our collection of dataGridView rows.
// So all we do is to throw the exception if the user wants. Otherwise we don't do anything.
dgvdee = new DataGridViewDataErrorEventArgs(exception,
-1,
rowIndex,
// null,
// null,
DataGridViewDataErrorContexts.RowDeletion);
OnDataErrorInternal(dgvdee);
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
else
{
remainingSelectedRows++;
}
}
if (dataGridRowsCount != this.Rows.Count)
{
Debug.Assert(dataGridViewRow.Index == -1);
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs(dataGridViewRow);
OnUserDeletedRow(dgvre);
}
else if (dgvdee == null)
{
remainingSelectedRows++;
}
}
else
{
this.Rows.RemoveAtInternal(rowIndex, false /*force*/);
Debug.Assert(dataGridViewRow.Index == -1);
DataGridViewRowEventArgs dgvre = new DataGridViewRowEventArgs(dataGridViewRow);
OnUserDeletedRow(dgvre);
}
}
else
{
remainingSelectedRows++;
}
}
}
}
finally
{
this.selectedBandSnapshotIndexes = null;
}
return true;
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessDialogKey"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets a value that indicates whether a key should be processed
/// further.
/// </para>
/// </devdoc>
[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
protected override bool ProcessDialogKey(Keys keyData)
{
Keys key = (keyData & Keys.KeyCode);
if (key == Keys.Enter)
{
if (ProcessEnterKey(keyData))
{
return true;
}
}
else if (key == Keys.Escape)
{
bool keyEffective = this.IsEscapeKeyEffective;
bool ret = base.ProcessDialogKey(keyData);
if (!keyEffective)
{
// This call may perform Click of Cancel button of form.
if (this.Focused)
{
// Make sure the current cell is in editing mode if needed.
if (this.ptCurrentCell.X > -1 &&
!this.IsCurrentCellInEditMode &&
(this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null)))
{
BeginEditInternal(true /*selectAll*/);
}
}
}
return ret;
}
else if (key == Keys.D0 || key == Keys.NumPad0)
{
if (ProcessZeroKey(keyData))
{
return true;
}
}
else if (key == Keys.C || key == Keys.Insert)
{
if (ProcessInsertKey(keyData))
{
return true;
}
}
else if (key == Keys.Tab)
{
IntSecurity.AllWindows.Demand();
if (ProcessTabKey(keyData))
{
return true;
}
else
{
if (this.editingControl != null)
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_leavingWithTabKey] = true;
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.LeaveControl,
DataGridViewValidateCellInternal.Always,
true /*fireCellLeave*/,
true /*fireCellEnter*/,
true /*fireRowLeave*/,
true /*fireRowEnter*/,
true /*fireLeave*/,
false /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell unused here*/))
{
return true;
}
}
keyData &= ~Keys.Control;
bool ret = false;
// SECREVIEW : ProcessDialogKey can generate a call to ContainerControl.SetActiveControl which demands ModifyFocus permission,
// we need to assert it here; the assert is safe, setting the active control does not expose any sec vulnerability
// indirectly.
//
IntSecurity.ModifyFocus.Assert();
try
{
ret = base.ProcessDialogKey(keyData);
}
finally
{
CodeAccessPermission.RevertAssert();
}
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_leavingWithTabKey] && this.Focused)
{
// There was no other control to tab to. The CellLeave, RowLeave, Leave events were raised.
// Since the DataGridView control still has the focus, Enter, RowEnter, CellEnter events need to be raised.
OnEnter(EventArgs.Empty);
}
return ret;
}
}
return base.ProcessDialogKey(keyData);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessDownKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessDownKey(Keys keyData)
{
bool moved;
return ProcessDownKeyInternal(keyData, out moved);
}
private bool ProcessDownKeyInternal(Keys keyData, out bool moved)
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
if (firstVisibleColumnIndex == -1 || lastVisibleRowIndex == -1)
{
moved = false;
return false;
}
int nextVisibleRowIndex = -1;
if (this.ptCurrentCell.Y != -1)
{
nextVisibleRowIndex = this.Rows.GetNextRow(this.ptCurrentCell.Y, DataGridViewElementStates.Visible);
}
moved = true;
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell
// the list under the DataGridView changes.
// In this case set moved to false so the users that call ProcessDownKey
// will commit the data.
// See vsWhidbey: 325296.
moved = false;
}
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
//ClearSelection();
Debug.Assert(this.ptAnchorCell.Y >= 0);
//SelectCellRange(this.ptCurrentCell.X, this.ptAnchorCell.Y, this.ptCurrentCell.X, lastVisibleRowIndex, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptCurrentCell.X == -1 || this.ptAnchorCell.X == -1 ||
IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, lastVisibleRowIndex);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, false, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
//SetSelectedCellCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, lastVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, lastVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (nextVisibleRowIndex == -1)
{
moved = false;
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, nextVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextVisibleRowIndex))
{
moved = false;
return true;
}
if (this.MultiSelect)
{
//SelectCellUnorderedRange(this.ptCurrentCell.X, this.ptAnchorCell.Y, this.ptCurrentCell.X, nextVisibleRowIndex, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
moved = false;
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, nextVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, nextVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextVisibleRowIndex, !this.MultiSelect, false, false);
if (!success)
{
moved = false;
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (nextVisibleRowIndex == -1)
{
moved = false;
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, nextVisibleRowIndex, true /*forCurrentCellChange*/))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextVisibleRowIndex))
{
moved = false;
return true;
}
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, nextVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X,
nextVisibleRowIndex,
true /*setAnchorCellAddress*/,
false /*validateCurrentCell*/,
false /*throughMouseClick*/);
if (!success)
{
moved = false;
}
}
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptAnchorCell.Y == -1 || this.ptCurrentCell.X == -1 ||
IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
ClearSelection();
Debug.Assert(this.ptAnchorCell.Y >= 0);
SelectRowRange(this.ptAnchorCell.Y, lastVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, false, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
SetSelectedRowCore(this.ptCurrentCell.Y, false);
SetSelectedRowCore(lastVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (nextVisibleRowIndex == -1)
{
moved = false;
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, nextVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextVisibleRowIndex))
{
moved = false;
return true;
}
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
moved = false;
return true;
}
if (nextVisibleRowIndex >= this.ptAnchorCell.Y)
{
SelectRowRange(this.ptAnchorCell.Y, nextVisibleRowIndex, true);
}
else
{
SelectRowRange(nextVisibleRowIndex, this.ptAnchorCell.Y, true);
}
}
else
{
SetSelectedRowCore(nextVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextVisibleRowIndex, !this.MultiSelect, false, false);
if (!success)
{
moved = false;
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (nextVisibleRowIndex == -1)
{
moved = false;
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, nextVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextVisibleRowIndex))
{
moved = false;
return true;
}
ClearSelection();
SetSelectedRowCore(nextVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
return true;
case DataGridViewSelectionMode.RowHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
Debug.Assert(this.ptAnchorCell.Y >= 0);
if (this.ptAnchorCell.Y == -1 || this.ptCurrentCell.Y == -1 ||
IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SelectRowRange(this.ptAnchorCell.Y, lastVisibleRowIndex, true);
}
else
{
//ClearSelection();
//SelectCellRange(this.ptCurrentCell.X, this.ptAnchorCell.Y, this.ptCurrentCell.X, lastVisibleRowIndex, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, lastVisibleRowIndex);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, false, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
SetSelectedRowCore(this.ptCurrentCell.Y, false);
SetSelectedRowCore(lastVisibleRowIndex, true);
}
else
{
SetSelectedCellCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
SetSelectedCellCore(this.ptCurrentCell.X, lastVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, lastVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (nextVisibleRowIndex == -1)
{
moved = false;
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, nextVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsRowOutOfBounds(nextVisibleRowIndex))
{
moved = false;
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.Y == -1)
{
moved = false;
return true;
}
if (nextVisibleRowIndex >= this.ptAnchorCell.Y)
{
SelectRowRange(this.ptAnchorCell.Y, nextVisibleRowIndex, true);
}
else
{
SelectRowRange(nextVisibleRowIndex, this.ptAnchorCell.Y, true);
}
}
else
{
SetSelectedRowCore(nextVisibleRowIndex, true);
}
}
else
{
if (this.MultiSelect)
{
//SelectCellUnorderedRange(this.ptCurrentCell.X, this.ptAnchorCell.Y, this.ptCurrentCell.X, nextVisibleRowIndex, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
moved = false;
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, nextVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, nextVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextVisibleRowIndex, !this.MultiSelect, false, false);
if (!success)
{
moved = false;
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, lastVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (nextVisibleRowIndex == -1)
{
moved = false;
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, nextVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsRowOutOfBounds(nextVisibleRowIndex))
{
moved = false;
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(nextVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, nextVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, lastVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, lastVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, lastVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
else
{
if (nextVisibleRowIndex == -1)
{
moved = false;
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, nextVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextVisibleRowIndex))
{
moved = false;
return true;
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextVisibleRowIndex, true, false, false);
if (!success)
{
moved = false;
}
}
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessEndKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessEndKey(Keys keyData)
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
int lastVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
if (lastVisibleColumnIndex == -1 || firstVisibleRowIndex == -1)
{
return false;
}
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, lastVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, lastVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.MultiSelect && this.ptAnchorCell.X >= 0)
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, lastVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, lastVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, lastVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, !this.MultiSelect, false, false);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, lastVisibleRowIndex, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
}
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
}
return true;
case DataGridViewSelectionMode.RowHeaderSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, lastVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, lastVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.MultiSelect && this.ptAnchorCell.X >= 0)
{
if (this.ptCurrentCell.Y > -1 &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SelectRowRange(this.ptCurrentCell.Y, lastVisibleRowIndex, true);
}
else
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, lastVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, lastVisibleRowIndex);
}
}
else
{
if (this.ptCurrentCell.Y > -1 &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, lastVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, !this.MultiSelect, false, false);
}
else
{
if (this.ptCurrentCell.Y > -1 &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(lastVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, lastVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
}
// Debug.Assert(success);
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, lastVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, lastVisibleRowIndex))
{
return true;
}
ClearSelection();
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.MultiSelect && this.ptCurrentCell.X >= 0)
{
SelectColumnRange(this.ptAnchorCell.X, lastVisibleColumnIndex, true);
}
else
{
SetSelectedColumnCore(lastVisibleColumnIndex, true);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, !this.MultiSelect, false, false);
}
else
{
SetSelectedColumnCore(lastVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
}
// Debug.Assert(success);
}
return true;
case DataGridViewSelectionMode.ColumnHeaderSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (!ScrollIntoView(lastVisibleColumnIndex, lastVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, lastVisibleRowIndex))
{
return true;
}
if (this.ptCurrentCell.X >= 0 && this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
SelectColumnRange(this.ptAnchorCell.X, lastVisibleColumnIndex, true);
}
SetSelectedColumnCore(lastVisibleColumnIndex, true);
}
else
{
if (this.MultiSelect && this.ptCurrentCell.X >= 0)
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, lastVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, lastVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, lastVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, !this.MultiSelect, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, lastVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, lastVisibleRowIndex))
{
return true;
}
if (this.ptCurrentCell.X >= 0 && this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SetSelectedColumnCore(lastVisibleColumnIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, lastVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, lastVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, lastVisibleRowIndex))
{
return true;
}
ClearSelection();
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.MultiSelect && this.ptCurrentCell.Y >= 0)
{
if (this.ptAnchorCell.Y == -1)
{
return true;
}
SelectRowRange(this.ptAnchorCell.Y, lastVisibleRowIndex, true);
}
else
{
SetSelectedRowCore(lastVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, !this.MultiSelect, false, false);
}
else
{
SetSelectedRowCore(lastVisibleRowIndex, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, lastVisibleRowIndex, true, false, false);
}
// Debug.Assert(success);
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessEnterKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessEnterKey(Keys keyData)
{
// commitRow is commented out for Dev10 bug 473789.
// When Enter is pressed, no matter Ctrl is also pressed or not,
// changes in a cell should be commited.
// Therefore, commitRow should be always true, and useless here.
bool moved = false, ret = true;//, commitRow = true;
if ((keyData & Keys.Control) == 0)
{
// Enter behaves like down arrow - it commits the potential editing and goes down one cell.
// commitRow = false;
keyData &= ~Keys.Shift;
ret = ProcessDownKeyInternal(keyData, out moved);
}
if (!moved)
{
DataGridViewCell dataGridViewCurrentCell = null;
// Try to commit the potential editing
if (this.EditMode == DataGridViewEditMode.EditOnEnter)
{
if (this.ptCurrentCell.X != -1)
{
dataGridViewCurrentCell = this.CurrentCellInternal;
DataGridViewDataErrorEventArgs dgvdee = CommitEdit(ref dataGridViewCurrentCell,
DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit,
DataGridViewValidateCellInternal.WhenChanged,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/);
if (null != dgvdee)
{
if (dgvdee.ThrowException)
{
throw dgvdee.Exception;
}
}
}
}
else
{
EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit,
DataGridViewValidateCellInternal.WhenChanged /*validateCell*/,
false /*fireCellLeave*/,
false /*fireCellEnter*/,
false /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
true /*keepFocus*/,
true /*resetCurrentCell unused here*/,
true /*resetAnchorCell unused here*/);
}
if (/*commitRow && */this.IsCurrentRowDirty)
{
dataGridViewCurrentCell = null;
int columnIndex = this.ptCurrentCell.X;
int rowIndex = this.ptCurrentCell.Y;
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return ret;
}
if (!OnRowValidating(ref dataGridViewCurrentCell, columnIndex, rowIndex))
{
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return ret;
}
OnRowValidated(ref dataGridViewCurrentCell, columnIndex, rowIndex);
}
}
}
return ret;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessEscapeKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode),
SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters") // Derived controls may need keyData.
]
protected bool ProcessEscapeKey(Keys keyData)
{
if (this.IsEscapeKeyEffective)
{
if (this.IsMouseOperationActive())
{
ResetTrackingState();
}
else
{
CancelEdit(true /*endEdit, DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.InitialValueRestoration*/);
}
return true;
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessF2Key"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode),
SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters") // Derived controls may need keyData.
]
protected bool ProcessF2Key(Keys keyData)
{
if (this.ptCurrentCell.X != -1 &&
!this.IsCurrentCellInEditMode &&
ModifierKeys == 0)
{
Debug.Assert(this.ptCurrentCell.Y != -1);
Debug.Assert(this.CurrentCellInternal != null);
Debug.Assert(this.EditMode != DataGridViewEditMode.EditOnEnter ||
(IsSharedCellReadOnly(this.CurrentCellInternal, this.ptCurrentCell.Y) || !ColumnEditable(this.ptCurrentCell.X)));
if (ColumnEditable(this.ptCurrentCell.X) &&
!IsSharedCellReadOnly(this.CurrentCellInternal, this.ptCurrentCell.Y) &&
(this.EditMode == DataGridViewEditMode.EditOnKeystrokeOrF2 ||
this.EditMode == DataGridViewEditMode.EditOnF2))
{
bool success = ScrollIntoView(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
Debug.Assert(success);
BeginEditInternal(this.EditMode == DataGridViewEditMode.EditOnF2 /*selectAll*/);
return true;
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessF3Key"]/*' />
/// <devdoc>
/// Sorts the current column.
/// 'UseLegacyAccessibilityFeatures2' accessibility switch
/// should be set to false to enable the feature.
/// </devdoc>
[
SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode),
]
protected bool ProcessF3Key(Keys keyData)
{
if (this.ptCurrentCell.X != -1 && AccessibilityImprovements.Level2)
{
DataGridViewColumn dataGridViewColumn = Columns[this.ptCurrentCell.X];
if (dataGridViewColumn != null && CanSort(dataGridViewColumn))
{
ListSortDirection listSortDirection = this.SortedColumn == dataGridViewColumn && this.SortOrder == SortOrder.Ascending ?
ListSortDirection.Descending : ListSortDirection.Ascending;
this.Sort(dataGridViewColumn, listSortDirection);
return true;
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessHomeKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessHomeKey(Keys keyData)
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (firstVisibleColumnIndex == -1 || firstVisibleRowIndex == -1)
{
return false;
}
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.MultiSelect && this.ptAnchorCell.X >= 0)
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, firstVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, firstVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, !this.MultiSelect, false, false);
}
else
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
}
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
}
return true;
case DataGridViewSelectionMode.RowHeaderSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.MultiSelect && this.ptAnchorCell.X >= 0)
{
if (this.ptCurrentCell.Y > -1 &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SelectRowRange(firstVisibleRowIndex, this.ptAnchorCell.Y, true);
}
else
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, firstVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, firstVisibleRowIndex);
}
}
else
{
if (this.ptCurrentCell.Y > -1 &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, !this.MultiSelect, false, false);
}
else
{
if (this.ptCurrentCell.Y > -1 &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
}
// Debug.Assert(success);
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
ClearSelection();
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.MultiSelect && this.ptCurrentCell.X >= 0)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
SelectColumnRange(firstVisibleColumnIndex, this.ptAnchorCell.X, true);
}
else
{
SetSelectedColumnCore(firstVisibleColumnIndex, true);
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, !this.MultiSelect, false, false);
}
else
{
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
}
// Debug.Assert(success);
}
return true;
case DataGridViewSelectionMode.ColumnHeaderSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (!ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
if (this.ptCurrentCell.X >= 0 && this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
SelectColumnRange(firstVisibleColumnIndex, this.ptAnchorCell.X, true);
}
SetSelectedColumnCore(firstVisibleColumnIndex, true);
}
else
{
if (this.MultiSelect && this.ptCurrentCell.X >= 0)
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, firstVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, firstVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, !this.MultiSelect, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
if (this.ptCurrentCell.X >= 0 && this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if ((keyData & Keys.Control) == 0)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, true))
{
return true;
}
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessInsertKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessInsertKey(Keys keyData)
{
if (((keyData & (Keys.Shift | Keys.Control | Keys.Alt)) == Keys.Control ||
((keyData & (Keys.Shift | Keys.Control | Keys.Alt)) == (Keys.Control | Keys.Shift) && (keyData & Keys.KeyCode) == Keys.C)) &&
this.ClipboardCopyMode != DataGridViewClipboardCopyMode.Disable)
{
DataObject dataObject = GetClipboardContent();
if (dataObject != null)
{
Clipboard.SetDataObject(dataObject);
return true;
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessKeyEventArgs"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode),
]
protected override bool ProcessKeyEventArgs(ref Message m)
{
if (m.Msg == NativeMethods.WM_SYSKEYDOWN || m.Msg == NativeMethods.WM_KEYDOWN)
{
if (this.ptCurrentCell.X != -1)
{
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCell != null);
if (!this.IsCurrentCellInEditMode &&
ColumnEditable(this.ptCurrentCell.X) &&
!IsSharedCellReadOnly(dataGridViewCell, this.ptCurrentCell.Y) &&
(this.EditMode == DataGridViewEditMode.EditOnKeystroke || this.EditMode == DataGridViewEditMode.EditOnKeystrokeOrF2))
{
KeyEventArgs ke = new KeyEventArgs((Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys);
if (ke.KeyCode != Keys.ProcessKey || (int) m.LParam != 0x01) // Changing IME context does not trigger editing mode
{
Type editControlType = dataGridViewCell.EditType;
Type editingCellInterface = null;
if (editControlType == null)
{
// Current cell does not have an editing control. Does it implement IDataGridViewEditingCell?
editingCellInterface = dataGridViewCell.GetType().GetInterface("System.Windows.Forms.IDataGridViewEditingCell");
}
if ((editControlType != null || editingCellInterface == null) &&
dataGridViewCell.KeyEntersEditMode(ke))
{
// Cell wants to go to edit mode
bool success = ScrollIntoView(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
Debug.Assert(success);
if (BeginEditInternal(!(ke.KeyCode == Keys.F2 && ModifierKeys == 0 && this.EditMode == DataGridViewEditMode.EditOnKeystrokeOrF2) /*selectAll*/))
{
// Forward the key message to the editing control if any
if (this.editingControl != null)
{
this.editingControl.SendMessage(m.Msg, m.WParam, m.LParam);
this.dataGridViewState1[DATAGRIDVIEWSTATE1_forwardCharMessage] = true;
return true;
}
}
}
}
}
}
}
else if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_forwardCharMessage] &&
(m.Msg == NativeMethods.WM_SYSCHAR || m.Msg == NativeMethods.WM_CHAR || m.Msg == NativeMethods.WM_IME_CHAR))
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_forwardCharMessage] = false;
if (this.editingControl != null)
{
this.editingControl.SendMessage(m.Msg, m.WParam, m.LParam);
return true;
}
}
return base.ProcessKeyEventArgs(ref m);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessKeyPreview"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected override bool ProcessKeyPreview(ref Message m)
{
bool dataGridViewWantsInputKey;
KeyEventArgs ke = new KeyEventArgs((Keys)((int)m.WParam) | ModifierKeys);
// Refactor the special keys into two parts.
// 1. Escape and Space exist in both WM_CHAR and WM_KEYDOWN, WM_KEYUP.
// 2. Other special keys do not exist in WM_CHAR message, and character code of WM_CHAR may have overlapped
// w/ some of the key code. (Like character code of lowcase "q" is 0x71, it's overlapped w/ Keys.F2). This
// may introduce problem when handling them.
if (m.Msg == NativeMethods.WM_CHAR)
{
switch (ke.KeyCode)
{
case Keys.Escape:
case Keys.Space:
dataGridViewWantsInputKey = true;
break;
default:
dataGridViewWantsInputKey = false;
break;
}
}
else
{
switch (ke.KeyCode)
{
case Keys.Delete:
case Keys.Down:
case Keys.End:
case Keys.Enter:
case Keys.Escape:
case Keys.F2:
case Keys.F3:
case Keys.Home:
case Keys.Left:
case Keys.Next:
case Keys.Prior:
case Keys.Right:
case Keys.Space:
case Keys.Tab:
case Keys.Up:
dataGridViewWantsInputKey = true;
break;
default:
dataGridViewWantsInputKey = false;
break;
}
}
if (this.editingControl != null && (m.Msg == NativeMethods.WM_KEYDOWN || m.Msg == NativeMethods.WM_SYSKEYDOWN))
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_currentCellWantsInputKey] = ((IDataGridViewEditingControl)this.editingControl).EditingControlWantsInputKey(ke.KeyData, dataGridViewWantsInputKey);
}
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_currentCellWantsInputKey])
{
return base.ProcessKeyPreview(ref m);
}
if (dataGridViewWantsInputKey)
{
if (m.Msg == NativeMethods.WM_KEYDOWN || m.Msg == NativeMethods.WM_SYSKEYDOWN)
{
if (ProcessDataGridViewKey(ke))
{
return true;
// Ctrl-Tab will be sent as a tab paired w/ a control on the KeyUp message
}
else
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_currentCellWantsInputKey] = true;
}
}
else
{
return true;
}
}
return base.ProcessKeyPreview(ref m);
}
private bool? ProcessColumnResize(Keys keyData, int step)
{
if (AccessibilityImprovements.Level2 && (keyData & Keys.Alt) == Keys.Alt && this.AllowUserToResizeColumns && this.ptCurrentCell.X != -1)
{
if (this.currentColSplitBar == -1)
{
DataGridViewColumn dataGridViewColumn = Columns[this.ptCurrentCell.X];
if (dataGridViewColumn != null && dataGridViewColumn.Resizable == DataGridViewTriState.True &&
(dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.None || dataGridViewColumn.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill))
{
BeginKeyboardColumnResize(this.ptCurrentCell.X);
return true;
}
return false;
}
else
{
int x = this.currentColSplitBar + step;
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackKeyboardColResize] && this.resizeClipRectangle.Contains(x, this.resizeClipRectangle.Top))
{
MoveRowHeadersOrColumnResize(x);
return true;
}
return false;
}
}
return null;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessLeftKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessLeftKey(Keys keyData)
{
if (this.RightToLeftInternal)
{
return ProcessRightKeyPrivate(keyData);
}
else
{
return ProcessLeftKeyPrivate(keyData);
}
}
private bool ProcessLeftKeyPrivate(Keys keyData)
{
bool? resizeResult = this.ProcessColumnResize(keyData, -this.keyboardResizeStep);
if (resizeResult.HasValue)
{
return resizeResult.Value;
}
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (firstVisibleColumnIndex == -1 || firstVisibleRowIndex == -1)
{
return false;
}
int previousVisibleColumnIndex = -1;
if (this.ptCurrentCell.X != -1)
{
dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[this.ptCurrentCell.X],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumn != null)
{
previousVisibleColumnIndex = dataGridViewColumn.Index;
}
}
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (previousVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(previousVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(previousVisibleColumnIndex))
{
return true;
}
if (this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.X >= 0);
//SelectCellUnorderedRange(previousVisibleColumnIndex, this.ptCurrentCell.Y, this.ptAnchorCell.X, this.ptCurrentCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, previousVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, !this.MultiSelect, false, false);
Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (previousVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(previousVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(previousVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true);
success = SetCurrentCellAddressCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (previousVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(previousVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(previousVisibleColumnIndex))
{
return true;
}
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
if (this.Columns.DisplayInOrder(this.ptAnchorCell.X, previousVisibleColumnIndex))
{
SelectColumnRange(this.ptAnchorCell.X, previousVisibleColumnIndex, true);
}
else
{
SelectColumnRange(previousVisibleColumnIndex, this.ptAnchorCell.X, true);
}
}
else
{
SetSelectedColumnCore(previousVisibleColumnIndex, true);
}
success = SetCurrentCellAddressCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, !this.MultiSelect, false, false);
Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (previousVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(previousVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(previousVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedColumnCore(previousVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.ColumnHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (previousVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(previousVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsColumnOutOfBounds(previousVisibleColumnIndex))
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
if (this.Columns.DisplayInOrder(this.ptAnchorCell.X, previousVisibleColumnIndex))
{
SelectColumnRange(this.ptAnchorCell.X, previousVisibleColumnIndex, true);
}
else
{
SelectColumnRange(previousVisibleColumnIndex, this.ptAnchorCell.X, true);
}
}
SetSelectedColumnCore(previousVisibleColumnIndex, true);
}
else
{
if (this.MultiSelect)
{
//SelectCellUnorderedRange(previousVisibleColumnIndex, this.ptCurrentCell.Y, this.ptAnchorCell.X, this.ptCurrentCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, previousVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
}
success = SetCurrentCellAddressCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, !this.MultiSelect, false, false);
Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (previousVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(previousVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsColumnOutOfBounds(previousVisibleColumnIndex))
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SetSelectedColumnCore(previousVisibleColumnIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessLeftMost((keyData & Keys.Shift) == Keys.Shift, firstVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (previousVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(previousVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(previousVisibleColumnIndex))
{
return true;
}
success = SetCurrentCellAddressCore(previousVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
// Ctrl Left <==> Home
// Shift Ctrl Left <==> Shift Home
private bool ProcessLeftMost(bool shift, int firstVisibleColumnIndex, int firstVisibleRowIndex)
{
bool success;
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
if (shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
//ClearSelection();
Debug.Assert(this.ptAnchorCell.X >= 0);
//SelectCellRange(firstVisibleColumnIndex, this.ptCurrentCell.Y, this.ptAnchorCell.X, this.ptCurrentCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1 || this.ptCurrentCell.X == -1 ||
IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, firstVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, false, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
//SetSelectedCellCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if (shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptAnchorCell.X == -1 || this.ptCurrentCell.Y == -1 ||
IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
ClearSelection();
Debug.Assert(this.ptAnchorCell.X >= 0);
SelectColumnRange(firstVisibleColumnIndex, this.ptAnchorCell.X, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, false, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
SetSelectedColumnCore(this.ptCurrentCell.X, false);
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.ColumnHeaderSelect:
if (shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptAnchorCell.X == -1 || this.ptCurrentCell.X == -1 ||
IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
Debug.Assert(this.ptAnchorCell.X >= 0);
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SelectColumnRange(firstVisibleColumnIndex, this.ptAnchorCell.X, true);
}
else
{
//ClearSelection();
//SelectCellRange(firstVisibleColumnIndex, this.ptCurrentCell.Y, this.ptAnchorCell.X, this.ptCurrentCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, firstVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, false, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 ||
IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
SetSelectedColumnCore(this.ptCurrentCell.X, false);
SetSelectedColumnCore(firstVisibleColumnIndex, true);
}
else
{
SetSelectedCellCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
SetSelectedCellCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(firstVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessNextKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessNextKey(Keys keyData)
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
if (firstVisibleColumnIndex == -1)
{
return false;
}
int nextScreenVisibleRowIndexTmp, nextScreenVisibleRowIndex = -1, jumpRows = 0;
if (this.ptCurrentCell.Y == -1)
{
nextScreenVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (nextScreenVisibleRowIndex == -1)
{
return false;
}
}
else
{
nextScreenVisibleRowIndex = this.ptCurrentCell.Y;
}
if ((this.Rows.GetRowState(nextScreenVisibleRowIndex) & DataGridViewElementStates.Frozen) != 0)
{
if (this.displayedBandsInfo.FirstDisplayedScrollingRow > 0)
{
int firstDisplayedScrollingRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
Debug.Assert(firstDisplayedScrollingRowIndex != -1);
if (!ScrollIntoView(this.ptCurrentCell.X == -1 ? firstVisibleColumnIndex : this.ptCurrentCell.X,
firstDisplayedScrollingRowIndex, true))
{
return true;
}
jumpRows = this.Rows.GetRowCount(DataGridViewElementStates.Visible,
this.ptCurrentCell.Y,
firstDisplayedScrollingRowIndex)-1;
}
else
{
jumpRows = this.displayedBandsInfo.NumTotallyDisplayedFrozenRows;
}
}
jumpRows += this.displayedBandsInfo.NumTotallyDisplayedScrollingRows;
nextScreenVisibleRowIndexTmp = nextScreenVisibleRowIndex;
Debug.Assert(nextScreenVisibleRowIndexTmp != -1);
if (jumpRows == 0)
{
jumpRows = 1;
}
while (jumpRows > 0 && nextScreenVisibleRowIndexTmp != -1)
{
nextScreenVisibleRowIndexTmp = this.Rows.GetNextRow(nextScreenVisibleRowIndex, DataGridViewElementStates.Visible);
if (nextScreenVisibleRowIndexTmp != -1)
{
nextScreenVisibleRowIndex = nextScreenVisibleRowIndexTmp;
jumpRows--;
}
}
this.noSelectionChangeCount++;
try
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
SetSelectedCellCore(firstVisibleColumnIndex, nextScreenVisibleRowIndex, true);
break;
case DataGridViewSelectionMode.FullRowSelect:
SetSelectedRowCore(nextScreenVisibleRowIndex, true);
break;
case DataGridViewSelectionMode.FullColumnSelect:
SetSelectedColumnCore(firstVisibleColumnIndex, true);
break;
}
success = ScrollIntoView(firstVisibleColumnIndex, nextScreenVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, nextScreenVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, nextScreenVisibleRowIndex, true, false, false);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
return true;
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, nextScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextScreenVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift && this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.Y >= 0);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.Y == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, nextScreenVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, nextScreenVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextScreenVisibleRowIndex, false, false, false);
Debug.Assert(success);
return true;
case DataGridViewSelectionMode.FullRowSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, nextScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextScreenVisibleRowIndex))
{
return true;
}
ClearSelection();
if ((keyData & Keys.Shift) == Keys.Shift && this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.Y >= 0);
if (this.ptAnchorCell.Y == -1)
{
return true;
}
if (this.ptAnchorCell.Y < nextScreenVisibleRowIndex)
{
SelectRowRange(this.ptAnchorCell.Y, nextScreenVisibleRowIndex, true);
}
else
{
SelectRowRange(nextScreenVisibleRowIndex, this.ptAnchorCell.Y, true);
}
}
else
{
SetSelectedRowCore(nextScreenVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextScreenVisibleRowIndex, false, false, false);
// Debug.Assert(success);
return true;
case DataGridViewSelectionMode.RowHeaderSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, nextScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextScreenVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift && this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.Y >= 0);
if (this.ptAnchorCell.Y == -1)
{
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
if (this.ptAnchorCell.Y < nextScreenVisibleRowIndex)
{
SelectRowRange(this.ptAnchorCell.Y, nextScreenVisibleRowIndex, true);
}
else
{
SelectRowRange(nextScreenVisibleRowIndex, this.ptAnchorCell.Y, true);
}
}
else
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, nextScreenVisibleRowIndex);
}
}
else
{
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(nextScreenVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, nextScreenVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextScreenVisibleRowIndex, !this.MultiSelect, false, false);
// Debug.Assert(success);
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, nextScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(nextScreenVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, nextScreenVisibleRowIndex, true, false, false);
// Debug.Assert(success);
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessPriorKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessPriorKey(Keys keyData)
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
if (firstVisibleColumnIndex == -1)
{
return false;
}
int previousScreenVisibleRowIndexTmp, previousScreenVisibleRowIndex = -1;
if (this.ptCurrentCell.Y == -1)
{
previousScreenVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (previousScreenVisibleRowIndex == -1)
{
return false;
}
}
else
{
previousScreenVisibleRowIndex = this.ptCurrentCell.Y;
}
int jumpRows;
if ((this.Rows.GetRowState(previousScreenVisibleRowIndex) & DataGridViewElementStates.Frozen) != 0)
{
jumpRows = this.displayedBandsInfo.NumTotallyDisplayedFrozenRows;
}
else
{
jumpRows = this.displayedBandsInfo.NumTotallyDisplayedScrollingRows;
}
if (jumpRows == 0)
{
jumpRows = 1;
}
previousScreenVisibleRowIndexTmp = previousScreenVisibleRowIndex;
Debug.Assert(previousScreenVisibleRowIndexTmp != -1);
while (jumpRows > 0 && previousScreenVisibleRowIndexTmp != -1)
{
previousScreenVisibleRowIndexTmp = this.Rows.GetPreviousRow(previousScreenVisibleRowIndex, DataGridViewElementStates.Visible);
if (previousScreenVisibleRowIndexTmp != -1)
{
previousScreenVisibleRowIndex = previousScreenVisibleRowIndexTmp;
}
jumpRows--;
}
if ((this.Rows.GetRowState(previousScreenVisibleRowIndex) & DataGridViewElementStates.Frozen) != 0)
{
// Make sure the first scrolling row is visible if any
int firstDisplayedScrollingRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
if (firstDisplayedScrollingRowIndex != -1 &&
!ScrollIntoView(this.ptCurrentCell.X == -1 ? firstVisibleColumnIndex : this.ptCurrentCell.X,
firstDisplayedScrollingRowIndex, true))
{
return true;
}
// Also, first visible frozen row should become current one - there is no reason to jump to another frozen row.
previousScreenVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
}
Debug.Assert(previousScreenVisibleRowIndex != -1);
this.noSelectionChangeCount++;
try
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
SetSelectedCellCore(firstVisibleColumnIndex, previousScreenVisibleRowIndex, true);
break;
case DataGridViewSelectionMode.FullRowSelect:
SetSelectedRowCore(previousScreenVisibleRowIndex, true);
break;
case DataGridViewSelectionMode.FullColumnSelect:
SetSelectedColumnCore(firstVisibleColumnIndex, true);
break;
}
success = ScrollIntoView(firstVisibleColumnIndex, previousScreenVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, previousScreenVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, previousScreenVisibleRowIndex, true, false, false);
// Debug.Assert(success);
return true;
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, previousScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousScreenVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift && this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.Y >= 0);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, previousScreenVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, previousScreenVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousScreenVisibleRowIndex, false, false, false);
// Debug.Assert(success);
return true;
case DataGridViewSelectionMode.FullRowSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, previousScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousScreenVisibleRowIndex))
{
return true;
}
ClearSelection();
if ((keyData & Keys.Shift) == Keys.Shift && this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.Y >= 0);
if (this.ptAnchorCell.Y == -1)
{
return true;
}
if (this.ptAnchorCell.Y < previousScreenVisibleRowIndex)
{
SelectRowRange(this.ptAnchorCell.Y, previousScreenVisibleRowIndex, true);
}
else
{
SelectRowRange(previousScreenVisibleRowIndex, this.ptAnchorCell.Y, true);
}
}
else
{
SetSelectedRowCore(previousScreenVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousScreenVisibleRowIndex, false, false, false);
// Debug.Assert(success);
return true;
case DataGridViewSelectionMode.RowHeaderSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, previousScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousScreenVisibleRowIndex))
{
return true;
}
if ((keyData & Keys.Shift) == Keys.Shift && this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.Y >= 0);
if (this.ptAnchorCell.Y == -1)
{
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
if (this.ptAnchorCell.Y < previousScreenVisibleRowIndex)
{
SelectRowRange(this.ptAnchorCell.Y, previousScreenVisibleRowIndex, true);
}
else
{
SelectRowRange(previousScreenVisibleRowIndex, this.ptAnchorCell.Y, true);
}
}
else
{
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, previousScreenVisibleRowIndex);
}
}
else
{
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(previousScreenVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, previousScreenVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousScreenVisibleRowIndex, !this.MultiSelect, false, false);
// Debug.Assert(success);
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if (!ScrollIntoView(this.ptCurrentCell.X, previousScreenVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousScreenVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousScreenVisibleRowIndex, true, false, false);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessRightKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessRightKey(Keys keyData)
{
if (this.RightToLeftInternal)
{
return ProcessLeftKeyPrivate(keyData);
}
else
{
return ProcessRightKeyPrivate(keyData);
}
}
private bool ProcessRightKeyPrivate(Keys keyData)
{
bool? resizeResult = this.ProcessColumnResize(keyData, this.keyboardResizeStep);
if (resizeResult.HasValue)
{
return resizeResult.Value;
}
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
int lastVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (lastVisibleColumnIndex == -1 || firstVisibleRowIndex == -1)
{
return false;
}
int nextVisibleColumnIndex = -1;
if (this.ptCurrentCell.X != -1)
{
dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[this.ptCurrentCell.X],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumn != null)
{
nextVisibleColumnIndex = dataGridViewColumn.Index;
}
}
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (nextVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(nextVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(nextVisibleColumnIndex))
{
return true;
}
if (this.MultiSelect)
{
//SelectCellUnorderedRange(this.ptAnchorCell.X, this.ptCurrentCell.Y, nextVisibleColumnIndex, this.ptCurrentCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.X == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, nextVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, !this.MultiSelect, false, false);
Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (nextVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(nextVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(nextVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true);
success = SetCurrentCellAddressCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(lastVisibleColumnIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (nextVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(nextVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(nextVisibleColumnIndex))
{
return true;
}
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
if (this.Columns.DisplayInOrder(this.ptAnchorCell.X, nextVisibleColumnIndex))
{
SelectColumnRange(this.ptAnchorCell.X, nextVisibleColumnIndex, true);
}
else
{
SelectColumnRange(nextVisibleColumnIndex, this.ptAnchorCell.X, true);
}
}
else
{
SetSelectedColumnCore(nextVisibleColumnIndex, true);
}
success = SetCurrentCellAddressCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, !this.MultiSelect, false, false);
Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(lastVisibleColumnIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (nextVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(nextVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(nextVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedColumnCore(nextVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.ColumnHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (nextVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(nextVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(nextVisibleColumnIndex))
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
if (this.Columns.DisplayInOrder(this.ptAnchorCell.X, nextVisibleColumnIndex))
{
SelectColumnRange(this.ptAnchorCell.X, nextVisibleColumnIndex, true);
}
else
{
SelectColumnRange(nextVisibleColumnIndex, this.ptAnchorCell.X, true);
}
}
else
{
SetSelectedColumnCore(nextVisibleColumnIndex, true);
}
}
else
{
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
//SelectCellUnorderedRange(this.ptAnchorCell.X, this.ptCurrentCell.Y, nextVisibleColumnIndex, this.ptCurrentCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, nextVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
}
success = SetCurrentCellAddressCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, !this.MultiSelect, false, false);
Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (nextVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(nextVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsColumnOutOfBounds(nextVisibleColumnIndex))
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SetSelectedColumnCore(nextVisibleColumnIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
return ProcessRightMost((keyData & Keys.Shift) == Keys.Shift, lastVisibleColumnIndex, firstVisibleRowIndex);
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (nextVisibleColumnIndex == -1)
{
return true;
}
if (!ScrollIntoView(nextVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(nextVisibleColumnIndex))
{
return true;
}
success = SetCurrentCellAddressCore(nextVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
// Ctrl Right <==> End
// Shift Ctrl Right <==> Shift End
private bool ProcessRightMost(bool shift, int lastVisibleColumnIndex, int firstVisibleRowIndex)
{
bool success;
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
if (shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(lastVisibleColumnIndex))
{
return true;
}
if (this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.X >= 0);
if (this.ptAnchorCell.X == -1)
{
return true;
}
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, lastVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, false, false, false);
Debug.Assert(success);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(lastVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if (shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(lastVisibleColumnIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(lastVisibleColumnIndex))
{
return true;
}
if (this.MultiSelect)
{
if (this.ptAnchorCell.X == -1)
{
return true;
}
ClearSelection();
Debug.Assert(this.ptAnchorCell.X >= 0);
SelectColumnRange(this.ptAnchorCell.X, lastVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, false, false, false);
Debug.Assert(success);
}
else
{
SetSelectedColumnCore(this.ptCurrentCell.X, false);
SetSelectedColumnCore(lastVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(lastVisibleColumnIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(lastVisibleColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedColumnCore(lastVisibleColumnIndex, true);
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.ColumnHeaderSelect:
if (shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(lastVisibleColumnIndex))
{
return true;
}
if (this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.X >= 0);
if (this.ptAnchorCell.X == -1)
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SelectColumnRange(this.ptAnchorCell.X, lastVisibleColumnIndex, true);
}
else
{
//ClearSelection();
//SelectCellRange(this.ptAnchorCell.X, this.ptCurrentCell.Y, lastVisibleColumnIndex, this.ptCurrentCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, lastVisibleColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, oldEdgeRowIndex);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, false, false, false);
Debug.Assert(success);
}
else
{
if (this.Columns[this.ptCurrentCell.X].Selected)
{
SetSelectedColumnCore(this.ptCurrentCell.X, false);
SetSelectedColumnCore(lastVisibleColumnIndex, true);
}
else
{
SetSelectedCellCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
SetSelectedCellCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(lastVisibleColumnIndex))
{
return true;
}
if (this.Columns[this.ptCurrentCell.X].Selected)
{
ClearSelection();
SetSelectedColumnCore(lastVisibleColumnIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true);
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(lastVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(lastVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
Debug.Assert(success);
}
else
{
if (!ScrollIntoView(lastVisibleColumnIndex, this.ptCurrentCell.Y, true))
{
return true;
}
if (this.ptCurrentCell.Y == -1 || IsColumnOutOfBounds(lastVisibleColumnIndex))
{
return true;
}
success = SetCurrentCellAddressCore(lastVisibleColumnIndex, this.ptCurrentCell.Y, true, false, false);
Debug.Assert(success);
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessSpaceKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessSpaceKey(Keys keyData)
{
if ((keyData & (Keys.Control | Keys.Shift | Keys.Alt)) == Keys.Shift &&
this.ptCurrentCell.X != -1)
{
this.noSelectionChangeCount++;
bool switchedToBulkPaint = false;
if (this.selectedBandIndexes.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
if (this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect)
{
// Same as clicking the column header cell
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != this.ptCurrentCell.X)
{
// deselect currently selected column
SetSelectedColumnCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
RemoveIndividuallySelectedCells();
if (!this.Columns[this.ptCurrentCell.X].Selected)
{
Debug.Assert(!this.selectedBandIndexes.Contains(this.ptCurrentCell.X));
SetSelectedColumnCore(this.ptCurrentCell.X, true);
}
return true;
}
else if (this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect)
{
// Same as clicking the row header cell
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != this.ptCurrentCell.Y)
{
// deselect currently selected row
SetSelectedRowCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
RemoveIndividuallySelectedCells();
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) == 0)
{
Debug.Assert(!this.selectedBandIndexes.Contains(this.ptCurrentCell.Y));
SetSelectedRowCore(this.ptCurrentCell.Y, true);
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessTabKey"]/*' />
/// <devdoc>
/// <para>
/// Gets a value indicating whether the Tab key should be processed.
/// </para>
/// </devdoc>
[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
protected bool ProcessTabKey(Keys keyData)
{
if (this.StandardTab)
{
if ((keyData & Keys.Control) == Keys.Control)
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (!this.VisibleCellExists || this.CurrentCellIsFirstVisibleCell)
{
// Goto previous control
return false;
}
else
{
// Goto previous cell
return TabToPreviousCell();
}
}
else
{
if (!this.VisibleCellExists || this.CurrentCellIsLastVisibleCell)
{
// Goto next control
return false;
}
else
{
// Goto next cell
return TabToNextCell();
}
}
}
else
{
/*
if ((keyData & Keys.Shift) == Keys.Shift)
{
// Goto previous control
}
else
{
// Goto next control
}
*/
return false;
}
}
else
{
if ((keyData & Keys.Control) == Keys.Control)
{
/*
if ((keyData & Keys.Shift) == Keys.Shift)
{
// Goto previous control
}
else
{
// Goto next control
}
*/
return false;
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (!this.VisibleCellExists || this.CurrentCellIsFirstVisibleCell)
{
// Goto previous control
return false;
}
else
{
// Goto previous cell
return TabToPreviousCell();
}
}
else
{
if (!this.VisibleCellExists || this.CurrentCellIsLastVisibleCell)
{
// Goto next control
return false;
}
else
{
// Goto next cell
return TabToNextCell();
}
}
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessDataGridViewKey"]/*' />
/// <devdoc>
/// <para>
/// Processes keys for dataGridView navigation.
/// </para>
/// </devdoc>
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode),
SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")
]
protected virtual bool ProcessDataGridViewKey(KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Tab:
{
return ProcessTabKey(e.KeyData);
}
case Keys.Up:
{
return ProcessUpKey(e.KeyData);
}
case Keys.Down:
{
return ProcessDownKey(e.KeyData);
}
case Keys.Next:
{
return ProcessNextKey(e.KeyData);
}
case Keys.Prior:
{
return ProcessPriorKey(e.KeyData);
}
case Keys.Left:
{
return ProcessLeftKey(e.KeyData);
}
case Keys.Right:
{
return ProcessRightKey(e.KeyData);
}
case Keys.F2:
{
return ProcessF2Key(e.KeyData);
}
case Keys.F3:
{
return ProcessF3Key(e.KeyData);
}
case Keys.Home:
{
return ProcessHomeKey(e.KeyData);
}
case Keys.D0:
case Keys.NumPad0:
{
return ProcessZeroKey(e.KeyData);
}
case Keys.Delete:
{
return ProcessDeleteKey(e.KeyData);
}
case Keys.End:
{
return ProcessEndKey(e.KeyData);
}
case Keys.Enter:
{
return ProcessEnterKey(e.KeyData);
}
case Keys.Escape:
{
return ProcessEscapeKey(e.KeyData);
}
case Keys.A:
{
return ProcessAKey(e.KeyData);
}
case Keys.C:
case Keys.Insert:
{
return ProcessInsertKey(e.KeyData);
}
case Keys.Space:
{
return ProcessSpaceKey(e.KeyData);
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessUpKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessUpKey(Keys keyData)
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (firstVisibleColumnIndex == -1 || firstVisibleRowIndex == -1)
{
return false;
}
int previousVisibleRowIndex = -1;
if (this.ptCurrentCell.Y != -1)
{
previousVisibleRowIndex = this.Rows.GetPreviousRow(this.ptCurrentCell.Y, DataGridViewElementStates.Visible);
}
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptAnchorCell.X == -1 || this.ptCurrentCell.X == -1 ||
IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
//ClearSelection();
Debug.Assert(this.ptAnchorCell.Y >= 0);
//SelectCellRange(this.ptCurrentCell.X, firstVisibleRowIndex, this.ptCurrentCell.X, this.ptAnchorCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, firstVisibleRowIndex);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, false, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
//SetSelectedCellCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, firstVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, firstVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (previousVisibleRowIndex == -1)
{
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, previousVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousVisibleRowIndex))
{
return true;
}
if (this.MultiSelect)
{
Debug.Assert(this.ptAnchorCell.Y >= 0);
if (this.ptAnchorCell.Y == -1)
{
return true;
}
//SelectCellUnorderedRange(this.ptCurrentCell.X, previousVisibleRowIndex, this.ptCurrentCell.X, this.ptAnchorCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, previousVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, previousVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousVisibleRowIndex, !this.MultiSelect, false, false);
// Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (previousVisibleRowIndex == -1)
{
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, previousVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousVisibleRowIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, previousVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.FullRowSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptAnchorCell.X == -1 || this.ptCurrentCell.X == -1 ||
IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
ClearSelection();
Debug.Assert(this.ptAnchorCell.Y >= 0);
SelectRowRange(firstVisibleRowIndex, this.ptAnchorCell.Y, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, false, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
SetSelectedRowCore(this.ptCurrentCell.Y, false);
SetSelectedRowCore(firstVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (previousVisibleRowIndex == -1)
{
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, previousVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousVisibleRowIndex))
{
return true;
}
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.Y == -1)
{
return true;
}
if (this.ptAnchorCell.Y >= previousVisibleRowIndex)
{
SelectRowRange(previousVisibleRowIndex, this.ptAnchorCell.Y, true);
}
else
{
SelectRowRange(this.ptAnchorCell.Y, previousVisibleRowIndex, true);
}
}
else
{
SetSelectedRowCore(previousVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousVisibleRowIndex, !this.MultiSelect, false, false);
// Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (previousVisibleRowIndex == -1)
{
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, previousVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousVisibleRowIndex))
{
return true;
}
ClearSelection();
SetSelectedRowCore(previousVisibleRowIndex, true);
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.RowHeaderSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (this.MultiSelect)
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptAnchorCell.X == -1 || this.ptCurrentCell.X == -1 ||
IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
Debug.Assert(this.ptAnchorCell.Y >= 0);
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SelectRowRange(firstVisibleRowIndex, this.ptAnchorCell.Y, true);
}
else
{
//ClearSelection();
//SelectCellRange(this.ptCurrentCell.X, firstVisibleRowIndex, this.ptCurrentCell.X, this.ptAnchorCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, firstVisibleRowIndex);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, false, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
SetSelectedRowCore(this.ptCurrentCell.Y, false);
SetSelectedRowCore(firstVisibleRowIndex, true);
}
else
{
SetSelectedCellCore(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
SetSelectedCellCore(this.ptCurrentCell.X, firstVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(firstVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, firstVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
else
{
if ((keyData & Keys.Shift) == Keys.Shift)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (previousVisibleRowIndex == -1)
{
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, previousVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousVisibleRowIndex))
{
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
if (this.MultiSelect)
{
if (this.ptAnchorCell.Y == -1)
{
return true;
}
if (this.ptAnchorCell.Y >= previousVisibleRowIndex)
{
SelectRowRange(previousVisibleRowIndex, this.ptAnchorCell.Y, true);
}
else
{
SelectRowRange(this.ptAnchorCell.Y, previousVisibleRowIndex, true);
}
}
SetSelectedRowCore(previousVisibleRowIndex, true);
}
else
{
if (this.MultiSelect)
{
//SelectCellUnorderedRange(this.ptCurrentCell.X, previousVisibleRowIndex, this.ptCurrentCell.X, this.ptAnchorCell.Y, true);
int oldEdgeColumnIndex = this.ptCurrentCell.X;
int oldEdgeRowIndex = this.ptCurrentCell.Y;
if (this.ptAnchorCell.Y == -1)
{
return true;
}
UpdateSelectedCellsBlock(this.ptAnchorCell.X, ref oldEdgeColumnIndex, oldEdgeColumnIndex,
this.ptAnchorCell.Y, ref oldEdgeRowIndex, previousVisibleRowIndex);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, previousVisibleRowIndex, true);
}
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousVisibleRowIndex, !this.MultiSelect, false, false);
// Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (previousVisibleRowIndex == -1)
{
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, previousVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousVisibleRowIndex))
{
return true;
}
if ((this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Selected) != 0)
{
ClearSelection();
SetSelectedRowCore(previousVisibleRowIndex, true);
}
else
{
ClearSelection();
SetSelectedCellCore(this.ptCurrentCell.X, previousVisibleRowIndex, true);
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
}
return true;
case DataGridViewSelectionMode.FullColumnSelect:
if ((keyData & Keys.Control) == Keys.Control)
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (!ScrollIntoView(this.ptCurrentCell.X, firstVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
else
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
SetSelectedColumnCore(firstVisibleColumnIndex, true);
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
else
{
if (previousVisibleRowIndex == -1)
{
return true;
}
if (!ScrollIntoView(this.ptCurrentCell.X, previousVisibleRowIndex, true))
{
return true;
}
if (this.ptCurrentCell.X == -1 || IsRowOutOfBounds(previousVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(this.ptCurrentCell.X, previousVisibleRowIndex, true, false, false);
// Debug.Assert(success);
}
}
return true;
}
}
finally
{
this.NoSelectionChangeCount--;
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ProcessZeroKey"]/*' />
[
SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)
]
protected bool ProcessZeroKey(Keys keyData)
{
if (this.ptCurrentCell.X != -1 && !this.IsCurrentCellInEditMode && ColumnEditable(this.ptCurrentCell.X))
{
DataGridViewCell dataGridViewCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCell != null);
if (!IsSharedCellReadOnly(dataGridViewCell, this.ptCurrentCell.Y) &&
(this.EditMode == DataGridViewEditMode.EditOnKeystroke || this.EditMode == DataGridViewEditMode.EditOnKeystrokeOrF2) &&
dataGridViewCell.EditType != null)
{
bool success = ScrollIntoView(this.ptCurrentCell.X, this.ptCurrentCell.Y, false);
Debug.Assert(success);
if (!BeginEditInternal(false /*selectAll*/))
{
return false;
}
}
}
if ((keyData & (Keys.Alt | Keys.Shift | Keys.Control)) == Keys.Control &&
this.IsCurrentCellInEditMode)
{
DataGridViewCell dataGridViewCurrentCell = this.CurrentCellInternal;
Debug.Assert(dataGridViewCurrentCell != null);
object nullValue = dataGridViewCurrentCell.GetInheritedStyle(null, this.ptCurrentCell.Y, false).NullValue;
if (nullValue == null ||
(dataGridViewCurrentCell.FormattedValueType != null && dataGridViewCurrentCell.FormattedValueType.IsAssignableFrom(nullValue.GetType())))
{
if (this.editingControl != null)
{
((IDataGridViewEditingControl) this.editingControl).EditingControlFormattedValue = nullValue;
((IDataGridViewEditingControl) this.editingControl).EditingControlValueChanged = true;
((IDataGridViewEditingControl) this.editingControl).PrepareEditingControlForEdit(true /*selectAll*/);
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
IDataGridViewEditingCell dataGridViewEditingCell = dataGridViewCurrentCell as IDataGridViewEditingCell;
Debug.Assert(dataGridViewEditingCell != null);
dataGridViewEditingCell.EditingCellFormattedValue = nullValue;
dataGridViewEditingCell.EditingCellValueChanged = true;
dataGridViewEditingCell.PrepareEditingCellForEdit(true /*selectAll*/);
InvalidateCellPrivate(this.ptCurrentCell.X, this.ptCurrentCell.Y);
}
NotifyCurrentCellDirty(true);
return true;
}
return false;
}
return false;
}
private void PushAllowUserToAddRows()
{
if (this.AllowUserToAddRowsInternal)
{
if (this.Columns.Count > 0 && this.newRowIndex == -1)
{
AddNewRow(false);
}
}
else if (this.newRowIndex != -1)
{
// Delete the 'new' row
Debug.Assert(this.newRowIndex == this.Rows.Count - 1);
this.Rows.RemoveAtInternal(this.newRowIndex, false /*force*/);
}
}
private bool PushFormattedValue(ref DataGridViewCell dataGridViewCurrentCell, object formattedValue, out Exception exception)
{
Debug.Assert(this.IsCurrentCellInEditMode);
exception = null;
DataGridViewCellStyle cellStyle = this.InheritedEditingCellStyle;
DataGridViewCellParsingEventArgs dgvcpe = OnCellParsing(this.ptCurrentCell.Y,
this.ptCurrentCell.X,
formattedValue,
dataGridViewCurrentCell.ValueType,
cellStyle);
if (dgvcpe.ParsingApplied &&
dgvcpe.Value != null &&
dataGridViewCurrentCell.ValueType != null &&
dataGridViewCurrentCell.ValueType.IsAssignableFrom(dgvcpe.Value.GetType()))
{
if (dataGridViewCurrentCell.RowIndex == -1)
{
dataGridViewCurrentCell = this.Rows[this.ptCurrentCell.Y].Cells[this.ptCurrentCell.X]; // unsharing the row before pushing the new value
}
return dataGridViewCurrentCell.SetValueInternal(this.ptCurrentCell.Y, dgvcpe.Value);
}
object val;
try
{
val = dataGridViewCurrentCell.ParseFormattedValue(formattedValue, dgvcpe.InheritedCellStyle, null, null);
}
catch (Exception e)
{
if (ClientUtils.IsCriticalException(e))
{
throw;
}
exception = e;
return false;
}
if (dataGridViewCurrentCell.RowIndex == -1)
{
dataGridViewCurrentCell = this.Rows[this.ptCurrentCell.Y].Cells[this.ptCurrentCell.X]; // unsharing the row before pushing the new value
}
return dataGridViewCurrentCell.SetValueInternal(this.ptCurrentCell.Y, val);
}
private void RecordCellMouseClick(DataGridViewCellMouseEventArgs dgvcme)
{
Debug.Assert(dgvcme.Clicks == 1);
this.lastMouseClickInfo.button = dgvcme.Button;
this.lastMouseClickInfo.timeStamp = DateTime.Now.Ticks;
this.lastMouseClickInfo.x = dgvcme.X;
this.lastMouseClickInfo.y = dgvcme.Y;
this.lastMouseClickInfo.col = dgvcme.ColumnIndex;
this.lastMouseClickInfo.row = dgvcme.RowIndex;
}
private void RefreshColumnsAndRows()
{
this.Rows.ClearInternal(false /*recreateNewRow*/);
RefreshColumns();
RefreshRows(true /*scrollIntoView*/);
}
private void RefreshColumns()
{
// if AutoGenerateColumns == true then:
// 1. remove the columns which were previously bound
// 2. add new columns based on data source
//
bool startUpdateInternal = this.Visible;
if (startUpdateInternal)
{
BeginUpdateInternal();
}
this.dataGridViewOper[DATAGRIDVIEWOPER_inRefreshColumns] = true;
try
{
DataGridViewColumnCollection dataGridViewCols = this.Columns;
DataGridViewColumn[] boundColumns = null;
if (this.dataConnection != null)
{
boundColumns = this.dataConnection.GetCollectionOfBoundDataGridViewColumns();
}
if (this.AutoGenerateColumns)
{
AutoGenerateDataBoundColumns(boundColumns);
}
else
{
for (int j = 0; j < dataGridViewCols.Count; j ++)
{
// when we refresh the columns, always clear whatever binding information we had on the columns
dataGridViewCols[j].IsDataBoundInternal = false;
dataGridViewCols[j].BoundColumnIndex = -1;
dataGridViewCols[j].BoundColumnConverter = null;
// set up the columns which have DataPropertyName set to something
if (this.DataSource != null && dataGridViewCols[j].DataPropertyName.Length != 0)
{
MapDataGridViewColumnToDataBoundField(dataGridViewCols[j]);
}
}
}
if (this.DataSource != null)
{
this.dataConnection.ApplySortingInformationFromBackEnd();
}
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inRefreshColumns] = false;
if (startUpdateInternal)
{
EndUpdateInternal(false);
Invalidate(true);
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.RefreshEdit"]/*' />
// Returns true for success, and false if an OnDataError event was raised and cancelled the operation (e.Cancel = true).
public bool RefreshEdit()
{
if (this.ptCurrentCell.X != -1 && this.IsCurrentCellInEditMode)
{
Debug.Assert(this.ptCurrentCell.Y != -1);
DataGridViewCell dataGridViewCurrentCell = this.CurrentCellInternal;
DataGridViewCellStyle dataGridViewCellStyle = dataGridViewCurrentCell.GetInheritedStyle(null, this.ptCurrentCell.Y, true);
if (this.editingControl != null)
{
if (InitializeEditingControlValue(ref dataGridViewCellStyle, dataGridViewCurrentCell))
{
if (((IDataGridViewEditingControl) this.editingControl).RepositionEditingControlOnValueChange)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
((IDataGridViewEditingControl) this.editingControl).PrepareEditingControlForEdit(true /*selectAll*/);
((IDataGridViewEditingControl) this.editingControl).EditingControlValueChanged = false;
this.IsCurrentCellDirtyInternal = false;
return true;
}
return false;
}
else
{
Debug.Assert(this.dataGridViewState1[DATAGRIDVIEWSTATE1_currentCellInEditMode]);
if (InitializeEditingCellValue(ref dataGridViewCellStyle, ref dataGridViewCurrentCell))
{
IDataGridViewEditingCell dataGridViewEditingCell = dataGridViewCurrentCell as IDataGridViewEditingCell;
Debug.Assert(dataGridViewEditingCell != null);
dataGridViewEditingCell.PrepareEditingCellForEdit(true /*selectAll*/);
dataGridViewEditingCell.EditingCellValueChanged = false;
this.IsCurrentCellDirtyInternal = false;
return true;
}
return false;
}
}
return true;
}
private void RefreshRows(bool scrollIntoView)
{
bool startBeginUpdate = this.Visible;
if (startBeginUpdate)
{
BeginUpdateInternal();
}
try
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inCurrentCellChange])
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_rowsCollectionClearedInSetCell] = true;
}
// Clear existing rows
this.Rows.ClearInternal(true /*recreateNewRow*/);
// Add a row for each object in the data source
if (this.dataConnection != null && this.Columns.Count > 0)
{
IList list = this.dataConnection.List;
if (list != null && list.Count > 0)
{
int rowsCount = list.Count;
bool oldDoNotChangePositionInTheCurrencyManager = this.dataConnection.DoNotChangePositionInTheCurrencyManager;
// scroll into view when we have a non-empty list
// and the layout is not dirty and we are not in a sort operation.
bool matchPositionInCurrencyManagerAfterRecreatingRows = !this.layout.dirty && !this.InSortOperation;
if (matchPositionInCurrencyManagerAfterRecreatingRows)
{
// Prevent the data connection from changing position in the currency manager.
// But only if the data grid view will set the position in the currency manager after recreating the rows collection.
this.dataConnection.DoNotChangePositionInTheCurrencyManager = true;
}
try
{
this.Rows.AddInternal(this.RowTemplateClone);
Debug.Assert(list.Count == rowsCount);
if (rowsCount > 1)
{
this.Rows.AddCopiesInternal(0, rowsCount-1);
}
// Add selected Columns back in selectedBandIndexes
foreach(DataGridViewColumn column in Columns)
{
if (column.Selected && (!this.selectedBandIndexes.Contains(column.Index)))
{
this.selectedBandIndexes.Add(column.Index);
}
}
}
finally
{
this.dataConnection.DoNotChangePositionInTheCurrencyManager = oldDoNotChangePositionInTheCurrencyManager;
}
if (matchPositionInCurrencyManagerAfterRecreatingRows)
{
dataConnection.MatchCurrencyManagerPosition(scrollIntoView, true /*clearSelection*/);
}
}
}
}
finally
{
if (startBeginUpdate)
{
EndUpdateInternal(false);
Invalidate(true);
}
}
}
private void RealeaseMouse()
{
Cursor.ClipInternal = Rectangle.Empty;
this.CaptureInternal = false;
}
private void RemoveIndividualReadOnlyCellsInColumn(int columnIndex)
{
int cellIndex = 0;
while (cellIndex < this.individualReadOnlyCells.Count)
{
DataGridViewCell dataGridViewCell = this.individualReadOnlyCells[cellIndex];
if (dataGridViewCell.ColumnIndex == columnIndex)
{
SetReadOnlyCellCore(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex, false);
}
else
{
cellIndex++;
}
}
}
private void RemoveIndividualReadOnlyCellsInRow(int rowIndex)
{
int cellIndex = 0;
while (cellIndex < this.individualReadOnlyCells.Count)
{
DataGridViewCell dataGridViewCell = this.individualReadOnlyCells[cellIndex];
if (dataGridViewCell.RowIndex == rowIndex)
{
SetReadOnlyCellCore(dataGridViewCell.ColumnIndex, rowIndex, false);
}
else
{
cellIndex++;
}
}
}
private void RemoveIndividuallySelectedCells()
{
Debug.Assert(this.noSelectionChangeCount > 0);
bool switchedToBulkPaint = false;
if (this.individualSelectedCells.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (this.individualSelectedCells.Count > 0)
{
DataGridViewCell dataGridViewCell = this.individualSelectedCells.HeadCell;
SetSelectedCellCore(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex, false);
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
private void RemoveIndividuallySelectedCells(int columnIndexException, int rowIndexException)
{
Debug.Assert(this.noSelectionChangeCount > 0);
bool switchedToBulkPaint = false;
if (this.individualSelectedCells.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
while (this.individualSelectedCells.Count > 0)
{
DataGridViewCell dataGridViewCell = this.individualSelectedCells.HeadCell;
if (dataGridViewCell.ColumnIndex != columnIndexException || dataGridViewCell.RowIndex != rowIndexException)
{
SetSelectedCellCore(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex, false);
}
else
{
while (this.individualSelectedCells.Count > 1)
{
dataGridViewCell = this.individualSelectedCells[1];
Debug.Assert(dataGridViewCell.ColumnIndex != columnIndexException || dataGridViewCell.RowIndex != rowIndexException);
SetSelectedCellCore(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex, false);
}
break;
}
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
private void RemoveIndividuallySelectedCellsInColumn(int columnIndex)
{
Debug.Assert(this.noSelectionChangeCount > 0);
int cellIndex = 0;
int cellCountInColumn = 0;
bool switchToBulkOperation = false;
DataGridViewCell dataGridViewCell;
while (cellIndex < this.individualSelectedCells.Count)
{
dataGridViewCell = this.individualSelectedCells[cellIndex];
if (dataGridViewCell.ColumnIndex == columnIndex)
{
SetSelectedCellCore(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex, false);
cellCountInColumn++;
if (cellCountInColumn > DATAGRIDVIEW_bulkPaintThreshold)
{
switchToBulkOperation = true;
break;
}
}
else
{
cellIndex++;
}
}
if (switchToBulkOperation)
{
this.inBulkPaintCount++;
try
{
while (cellIndex < this.individualSelectedCells.Count)
{
dataGridViewCell = this.individualSelectedCells[cellIndex];
if (dataGridViewCell.ColumnIndex == columnIndex)
{
SetSelectedCellCore(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex, false);
}
else
{
cellIndex++;
}
}
}
finally
{
ExitBulkPaint(columnIndex, -1);
}
}
}
private void RemoveIndividuallySelectedCellsInRow(int rowIndex)
{
Debug.Assert(this.noSelectionChangeCount > 0);
// Since there are typically not many columns in a row, we don't try to switch into a bulk operation
// as we do in RemoveIndividuallySelectedCellsInColumn.
int cellIndex = 0;
while (cellIndex < this.individualSelectedCells.Count)
{
DataGridViewCell dataGridViewCell = this.individualSelectedCells[cellIndex];
if (dataGridViewCell.RowIndex == rowIndex)
{
SetSelectedCellCore(dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex, false);
}
else
{
cellIndex++;
}
}
}
// required by the Designer
private void ResetBackgroundColor()
{
this.BackgroundColor = DefaultBackgroundBrush.Color;
}
// required by the Designer
private void ResetGridColor()
{
this.GridColor = DefaultGridColor;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.ResetText"]/*' />
[EditorBrowsable(EditorBrowsableState.Never)]
public override void ResetText()
{
base.ResetText();
}
/// <devdoc>
/// Re-initializes all tracking related state.
/// </devdoc>
private void ResetTrackingState()
{
if (this.IsKeyboardOperationActive())
{
return;
}
if (this.horizScrollTimer != null && this.horizScrollTimer.Enabled)
{
this.horizScrollTimer.Enabled = false;
}
if (this.vertScrollTimer != null && this.vertScrollTimer.Enabled)
{
this.vertScrollTimer.Enabled = false;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_mouseOperationMask] = false;
this.dataGridViewOper[DATAGRIDVIEWOPER_trackColSelect] = false;
this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] = false;
this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect] = false;
this.trackColumn = -1;
this.trackRow = -1;
this.ptMouseDownCell.X = -2;
this.ptMouseDownCell.Y = -2;
if (this.currentRowSplitBar != -1)
{
Invalidate(CalcRowResizeFeedbackRect(this.currentRowSplitBar), true);
this.lastRowSplitBar = this.currentRowSplitBar = -1;
}
if (this.currentColSplitBar != -1)
{
Invalidate(CalcColResizeFeedbackRect(this.currentColSplitBar), true);
this.lastColSplitBar = this.currentColSplitBar = -1;
}
if (this.lastHeaderShadow != -1)
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_showColumnRelocationInsertion] = false;
this.trackColumnEdge = -1;
this.lastHeaderShadow = -1;
Invalidate(Rectangle.Union(this.layout.TopLeftHeader, this.layout.ColumnHeaders));
}
RealeaseMouse();
}
// Re-initializes all state that is related to tracking keyboard operations
private void ResetKeyboardTrackingState()
{
if (this.IsMouseOperationActive())
{
return;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_keyboardOperationMask] = false;
this.trackColumn = -1;
if (this.currentColSplitBar != -1)
{
Invalidate(CalcColResizeFeedbackRect(this.currentColSplitBar), true);
this.lastColSplitBar = this.currentColSplitBar = -1;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool IsMouseOperationActive()
{
return (this.dataGridViewOper.Data & DATAGRIDVIEWOPER_mouseOperationMask) != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool IsKeyboardOperationActive()
{
return (this.dataGridViewOper.Data & DATAGRIDVIEWOPER_keyboardOperationMask) != 0;
}
/// <devdoc>
/// Re-initializes all UI related state.
/// </devdoc>
internal void ResetUIState(bool useRowShortcut, bool computeVisibleRows)
{
PerformLayoutPrivate(useRowShortcut, computeVisibleRows, true /*invalidInAdjustFillingColumns*/, !useRowShortcut /*repositionEditingControl*/);
if (!useRowShortcut)
{
Invalidate();
InvalidateScrollBars();
}
}
private void RestoreRowsCachedThickness()
{
// Switch to batch operation
this.inBulkPaintCount++;
this.inBulkLayoutCount++;
try
{
// Only height of visible rows are restored since invisible rows are not autosized.
for (int rowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
rowIndex != -1;
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible))
{
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
int height, minimumHeight;
dataGridViewRow.GetHeightInfo(rowIndex, out height, out minimumHeight);
if (height != dataGridViewRow.CachedThickness &&
!OnRowHeightInfoPushed(rowIndex, dataGridViewRow.CachedThickness, minimumHeight))
{
dataGridViewRow.ThicknessInternal = dataGridViewRow.CachedThickness;
}
}
}
finally
{
ExitBulkLayout(true /*invalidInAdjustFillingColumns*/);
ExitBulkPaint(-1, -1);
}
}
// we need to access the GetRowState, otherwise we would unshare the row
private bool RowIsResizable(int rowIndex)
{
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if ((rowState & DataGridViewElementStates.ResizableSet) == DataGridViewElementStates.ResizableSet)
{
return (rowState & DataGridViewElementStates.Resizable) == DataGridViewElementStates.Resizable;
}
else
{
return this.AllowUserToResizeRows;
}
}
private bool RowNeedsDisplayedState(int rowIndex, int lastDisplayedFrozenRowIndex, int lastDisplayedScrollingRowIndex)
{
Debug.Assert(rowIndex >= 0);
Debug.Assert(rowIndex < this.Rows.Count);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if ((rowState & DataGridViewElementStates.Visible) == 0)
{
return false;
}
if ((rowState & DataGridViewElementStates.Frozen) != 0)
{
return rowIndex <= lastDisplayedFrozenRowIndex;
}
else if (this.displayedBandsInfo.FirstDisplayedScrollingRow != -1 &&
rowIndex >= this.displayedBandsInfo.FirstDisplayedScrollingRow &&
rowIndex <= lastDisplayedScrollingRowIndex)
{
return true;
}
return false;
}
private void ScrollBar_MouseEnter(object sender, System.EventArgs e)
{
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_mouseEnterExpected])
{
OnMouseEnter(EventArgs.Empty);
}
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
}
private void ScrollBar_MouseLeave(object sender, System.EventArgs e)
{
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
Point ptMouse = PointToClient(Control.MousePosition);
if (!this.ClientRectangle.Contains(ptMouse))
{
OnMouseLeave(EventArgs.Empty);
}
}
private bool ScrollColumnIntoView(int columnIndex, int rowIndex, bool committed, bool forCurrentCellChange)
{
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count);
if (this.displayedBandsInfo.FirstDisplayedScrollingCol != -1 &&
!this.Columns[columnIndex].Frozen &&
(columnIndex != this.displayedBandsInfo.FirstDisplayedScrollingCol || this.negOffset > 0))
{
int columnsToScroll;
if (this.Columns.DisplayInOrder(columnIndex, this.displayedBandsInfo.FirstDisplayedScrollingCol))
{
if (!committed && this.ptCurrentCell.X >= 0 &&
!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
forCurrentCellChange && (this.ptCurrentCell.X != columnIndex || this.ptCurrentCell.Y != rowIndex),
this.ptCurrentCell.Y != rowIndex /*forCurrentRowChange*/))
{
return false;
}
columnsToScroll = this.Columns.GetColumnCount(DataGridViewElementStates.Visible, columnIndex, this.displayedBandsInfo.FirstDisplayedScrollingCol);
if (this.negOffset > 0)
{
columnsToScroll++;
}
ScrollColumns(-columnsToScroll);
}
else if (columnIndex == this.displayedBandsInfo.FirstDisplayedScrollingCol && this.negOffset > 0)
{
if (!committed && this.ptCurrentCell.X >= 0 &&
!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
forCurrentCellChange && (this.ptCurrentCell.X != columnIndex || this.ptCurrentCell.Y != rowIndex),
this.ptCurrentCell.Y != rowIndex /*forCurrentRowChange*/))
{
return false;
}
ScrollColumns(-1);
}
else if (this.displayedBandsInfo.LastTotallyDisplayedScrollingCol == -1 ||
(this.displayedBandsInfo.LastTotallyDisplayedScrollingCol != columnIndex &&
this.Columns.DisplayInOrder(this.displayedBandsInfo.LastTotallyDisplayedScrollingCol, columnIndex)))
{
if (!committed && this.ptCurrentCell.X >= 0 &&
!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
forCurrentCellChange && (this.ptCurrentCell.X != columnIndex || this.ptCurrentCell.Y != rowIndex),
this.ptCurrentCell.Y != rowIndex /*forCurrentRowChange*/))
{
return false;
}
columnsToScroll = 0;
int firstDisplayedScrollingColumn = this.displayedBandsInfo.FirstDisplayedScrollingCol;
int xColumnRightEdge;
if (this.RightToLeftInternal)
{
xColumnRightEdge = GetColumnXFromIndex(columnIndex) - this.Columns[columnIndex].Width;
while (xColumnRightEdge < this.layout.Data.X && this.Columns.DisplayInOrder(firstDisplayedScrollingColumn, columnIndex))
{
xColumnRightEdge += this.Columns[firstDisplayedScrollingColumn].Width;
if (firstDisplayedScrollingColumn == this.displayedBandsInfo.FirstDisplayedScrollingCol)
{
xColumnRightEdge -= this.negOffset;
}
columnsToScroll++;
if (xColumnRightEdge < this.layout.Data.X)
{
firstDisplayedScrollingColumn = this.Columns.GetNextColumn(this.Columns[firstDisplayedScrollingColumn],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None).Index;
}
}
}
else
{
xColumnRightEdge = GetColumnXFromIndex(columnIndex) + this.Columns[columnIndex].Width;
while (xColumnRightEdge > this.layout.Data.Right && this.Columns.DisplayInOrder(firstDisplayedScrollingColumn, columnIndex))
{
xColumnRightEdge -= this.Columns[firstDisplayedScrollingColumn].Width;
if (firstDisplayedScrollingColumn == this.displayedBandsInfo.FirstDisplayedScrollingCol)
{
xColumnRightEdge += this.negOffset;
}
columnsToScroll++;
if (xColumnRightEdge > this.layout.Data.Right)
{
firstDisplayedScrollingColumn = this.Columns.GetNextColumn(this.Columns[firstDisplayedScrollingColumn],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None).Index;
}
}
}
if (columnsToScroll != 0)
{
ScrollColumns(columnsToScroll);
}
}
}
return true;
}
private void ScrollColumns(int columns)
{
DataGridViewColumn newFirstVisibleScrollingCol = null;
DataGridViewColumn dataGridViewColumnTmp;
int colCount = 0;
//ScrollEventType scrollEventType;
if (columns > 0)
{
//scrollEventType = columns > 1 ? ScrollEventType.LargeIncrement : ScrollEventType.SmallIncrement;
if (this.displayedBandsInfo.LastTotallyDisplayedScrollingCol >= 0)
{
dataGridViewColumnTmp = this.Columns[this.displayedBandsInfo.LastTotallyDisplayedScrollingCol];
while (colCount < columns && dataGridViewColumnTmp != null)
{
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
colCount++;
}
if (dataGridViewColumnTmp == null)
{
// no more column to display on the right of the last totally seen column
return;
}
}
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0);
dataGridViewColumnTmp = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
colCount = 0;
while (colCount < columns && dataGridViewColumnTmp != null)
{
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
colCount++;
}
newFirstVisibleScrollingCol = dataGridViewColumnTmp;
}
if (columns < 0)
{
//scrollEventType = columns < -1 ? ScrollEventType.LargeDecrement : ScrollEventType.SmallDecrement;
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingCol >= 0);
dataGridViewColumnTmp = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
if (this.negOffset > 0)
{
colCount++;
}
while (colCount < -columns && dataGridViewColumnTmp != null)
{
dataGridViewColumnTmp = this.Columns.GetPreviousColumn(dataGridViewColumnTmp,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
colCount++;
}
newFirstVisibleScrollingCol = dataGridViewColumnTmp;
if (newFirstVisibleScrollingCol == null)
{
if (this.negOffset == 0)
{
// no more column to display on the left of the first seen column
FlushDisplayedChanged();
return;
}
else
{
newFirstVisibleScrollingCol = this.Columns[this.displayedBandsInfo.FirstDisplayedScrollingCol];
}
}
}
int newColOffset = 0;
for (DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
dataGridViewColumn != newFirstVisibleScrollingCol;
dataGridViewColumn = this.Columns.GetNextColumn(dataGridViewColumn,
DataGridViewElementStates.Visible,
DataGridViewElementStates.None))
{
newColOffset += dataGridViewColumn.Thickness;
}
this.HorizontalOffset = newColOffset;
}
private bool ScrollIntoView(int columnIndex, int rowIndex, bool forCurrentCellChange)
{
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count);
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingCol >= -1 && this.displayedBandsInfo.FirstDisplayedScrollingCol < this.Columns.Count);
Debug.Assert(this.displayedBandsInfo.LastTotallyDisplayedScrollingCol >= -1 && this.displayedBandsInfo.LastTotallyDisplayedScrollingCol < this.Columns.Count);
Debug.Assert(rowIndex >= 0 && rowIndex < this.Rows.Count);
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= -1 && this.displayedBandsInfo.FirstDisplayedScrollingRow < this.Rows.Count);
Debug.Assert(this.Columns[columnIndex].Visible);
Debug.Assert((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) != 0);
bool committed = false;
if (this.ptCurrentCell.X >= 0 &&
(this.ptCurrentCell.X != columnIndex || this.ptCurrentCell.Y != rowIndex))
{
if (!CommitEditForOperation(columnIndex, rowIndex, forCurrentCellChange))
{
return false;
}
committed = true;
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
}
//scroll horizontally
if (!ScrollColumnIntoView(columnIndex, rowIndex, committed, forCurrentCellChange))
{
return false;
}
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
//scroll vertically
return ScrollRowIntoView(columnIndex, rowIndex, committed, forCurrentCellChange);
}
private void ScrollRectangles(NativeMethods.RECT[] rects, int change)
{
if (rects != null)
{
if (MouseButtons != MouseButtons.None)
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_scrolledSinceMouseDown] = true;
}
NativeMethods.RECT scroll;
for (int r = 0; r < rects.Length; r++)
{
scroll = rects[r];
SafeNativeMethods.ScrollWindow(new HandleRef(this, this.Handle),
change,
0,
ref scroll,
ref scroll);
}
}
}
private bool ScrollRowIntoView(int columnIndex, int rowIndex, bool committed, bool forCurrentCellChange)
{
Debug.Assert(rowIndex >= 0 && rowIndex < this.Rows.Count);
if ((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Frozen) == 0)
{
int rowsToScroll;
if (rowIndex < this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
if (!committed && this.ptCurrentCell.X >= 0 &&
!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
forCurrentCellChange && (this.ptCurrentCell.X != columnIndex || this.ptCurrentCell.Y != rowIndex),
this.ptCurrentCell.Y != rowIndex /*forCurrentRowChange*/))
{
return false;
}
rowsToScroll = this.Rows.GetRowCount(DataGridViewElementStates.Visible, rowIndex, this.displayedBandsInfo.FirstDisplayedScrollingRow);
ScrollRowsByCount(-rowsToScroll, rowsToScroll > 1 ? ScrollEventType.LargeDecrement : ScrollEventType.SmallDecrement);
}
else if (this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0 &&
rowIndex > this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
rowsToScroll = 0;
int firstDisplayedScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
int yRowBottomEdge = GetRowYFromIndex(rowIndex) + this.Rows.SharedRow(rowIndex).GetHeight(rowIndex);
while (yRowBottomEdge > this.layout.Data.Bottom && rowIndex > firstDisplayedScrollingRow)
{
yRowBottomEdge -= this.Rows.SharedRow(firstDisplayedScrollingRow).GetHeight(firstDisplayedScrollingRow);
rowsToScroll++;
if (yRowBottomEdge > this.layout.Data.Bottom)
{
firstDisplayedScrollingRow = this.Rows.GetNextRow(firstDisplayedScrollingRow, DataGridViewElementStates.Visible);
Debug.Assert(firstDisplayedScrollingRow != -1);
}
}
if (rowsToScroll != 0)
{
if (!committed && this.ptCurrentCell.X >= 0 &&
!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
forCurrentCellChange && (this.ptCurrentCell.X != columnIndex || this.ptCurrentCell.Y != rowIndex),
this.ptCurrentCell.Y != rowIndex /*forCurrentRowChange*/))
{
return false;
}
ScrollRowsByCount(rowsToScroll, rowsToScroll > 1 ? ScrollEventType.LargeIncrement : ScrollEventType.SmallIncrement);
}
}
}
return true;
}
private void ScrollRows(int rowCount, int deltaY, ScrollEventType scrollEventType)
{
bool invalidateTopOfRowHeaders = false;
Debug.Assert(rowCount != 0);
Debug.Assert(deltaY != 0);
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen));
this.verticalOffset -= deltaY;
if (this.vertScrollBar.Enabled)
{
this.vertScrollBar.Value = this.verticalOffset;
}
ClearRegionCache();
int frozenRowsThickness = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
Rectangle rowsRect = this.layout.Data;
if (this.layout.RowHeadersVisible)
{
rowsRect = Rectangle.Union(rowsRect, this.layout.RowHeaders);
if (this.SingleHorizontalBorderAdded)
{
rowsRect.Y++;
rowsRect.Height--;
invalidateTopOfRowHeaders = true;
}
}
else if (this.SingleVerticalBorderAdded)
{
Debug.Assert(rowsRect.X > 0);
rowsRect.X--;
rowsRect.Width++;
}
rowsRect.Y += frozenRowsThickness;
rowsRect.Height -= frozenRowsThickness;
Debug.Assert(rowsRect.Height >= 0);
if (this.editingControl != null &&
(this.Rows.GetRowState(this.ptCurrentCell.Y) & DataGridViewElementStates.Frozen) == 0)
{
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow > -1);
PositionEditingControl(true /*setLocation*/, false /*setSize*/, false /*setFocus*/);
}
if (MouseButtons != MouseButtons.None)
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_scrolledSinceMouseDown] = true;
}
// The mouse probably is not over the same cell after the scroll.
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
NativeMethods.RECT scrollArea = NativeMethods.RECT.FromXYWH(rowsRect.X, rowsRect.Y, rowsRect.Width, rowsRect.Height);
SafeNativeMethods.ScrollWindow(new HandleRef(this, this.Handle), 0, deltaY, ref scrollArea, ref scrollArea);
if (invalidateTopOfRowHeaders)
{
rowsRect.X = this.layout.Inside.X;
rowsRect.Y = this.layout.Inside.Y;
rowsRect.Width = this.layout.RowHeaders.Width;
rowsRect.Height = 1;
Invalidate(rowsRect);
}
if (!this.dataGridViewState2[DATAGRIDVIEWSTATE2_stopRaisingVerticalScroll])
{
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
int firstVisibleScrollingRow = this.Rows.GetFirstRow(DataGridViewElementStates.Visible, DataGridViewElementStates.Frozen);
Debug.Assert(firstVisibleScrollingRow != -1);
int newScrolledOffRowCount = this.Rows.GetRowCount(DataGridViewElementStates.Visible, firstVisibleScrollingRow, this.displayedBandsInfo.FirstDisplayedScrollingRow);
Debug.Assert(newScrolledOffRowCount >= rowCount);
OnScroll(scrollEventType, newScrolledOffRowCount - rowCount, newScrolledOffRowCount, ScrollOrientation.VerticalScroll);
}
}
private void ScrollRowsByCount(int rows, ScrollEventType scrollEventType)
{
Debug.Assert(rows != 0);
Debug.Assert((rows > 0 && (scrollEventType == ScrollEventType.SmallIncrement || scrollEventType == ScrollEventType.LargeIncrement)) ||
(rows < 0 && (scrollEventType == ScrollEventType.SmallDecrement || scrollEventType == ScrollEventType.LargeDecrement)));
int deltaY = 0;
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
int newFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
if (rows > 0)
{
for (int rowCount = rows; rowCount > 0; rowCount--)
{
deltaY -= this.Rows.SharedRow(newFirstVisibleScrollingRow).GetHeight(newFirstVisibleScrollingRow);
newFirstVisibleScrollingRow = this.Rows.GetNextRow(newFirstVisibleScrollingRow,
DataGridViewElementStates.Visible);
Debug.Assert(newFirstVisibleScrollingRow != -1);
}
if (newFirstVisibleScrollingRow != -1)
{
int oldFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
// Tentative target value for this.displayedBandsInfo.FirstDisplayedScrollingRow.
this.displayedBandsInfo.FirstDisplayedScrollingRow = newFirstVisibleScrollingRow;
// This sets the actual value of this.displayedBandsInfo.FirstDisplayedScrollingRow
ComputeVisibleRows();
// Compute the actual deltaY given the new this.displayedBandsInfo.FirstDisplayedScrollingRow
if (this.displayedBandsInfo.FirstDisplayedScrollingRow > oldFirstVisibleScrollingRow)
{
deltaY = -this.Rows.GetRowsHeight(DataGridViewElementStates.Visible, oldFirstVisibleScrollingRow, this.displayedBandsInfo.FirstDisplayedScrollingRow);
rows = this.Rows.GetRowCount(DataGridViewElementStates.Visible, oldFirstVisibleScrollingRow, this.displayedBandsInfo.FirstDisplayedScrollingRow);
}
else
{
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow == oldFirstVisibleScrollingRow);
rows = 0;
}
}
}
else
{
for (int rowCount = rows; rowCount < 0; rowCount++)
{
newFirstVisibleScrollingRow = this.Rows.GetPreviousRow(newFirstVisibleScrollingRow,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
if (newFirstVisibleScrollingRow != -1)
{
deltaY += this.Rows.SharedRow(newFirstVisibleScrollingRow).GetHeight(newFirstVisibleScrollingRow);
}
}
if (newFirstVisibleScrollingRow != -1)
{
this.displayedBandsInfo.FirstDisplayedScrollingRow = newFirstVisibleScrollingRow;
ComputeVisibleRows();
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow == newFirstVisibleScrollingRow);
}
}
if (newFirstVisibleScrollingRow != -1 && rows != 0)
{
ScrollRows(rows, deltaY, scrollEventType);
}
FlushDisplayedChanged();
}
private void ScrollRowsByHeight(int height)
{
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
int deltaY, scrollHeight = 0;
int oldFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
int newFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
if (height > 0)
{
deltaY = this.Rows.SharedRow(newFirstVisibleScrollingRow).GetHeight(newFirstVisibleScrollingRow);
while (deltaY <= height)
{
newFirstVisibleScrollingRow = this.Rows.GetNextRow(newFirstVisibleScrollingRow, DataGridViewElementStates.Visible);
if (newFirstVisibleScrollingRow == -1)
{
throw new InvalidOperationException(); // Occurs in case of VSWhidbey 533407
}
else
{
deltaY += this.Rows.SharedRow(newFirstVisibleScrollingRow).GetHeight(newFirstVisibleScrollingRow);
}
}
}
else
{
newFirstVisibleScrollingRow = this.Rows.GetPreviousRow(newFirstVisibleScrollingRow,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
Debug.Assert(newFirstVisibleScrollingRow != -1);
deltaY = -this.Rows.SharedRow(newFirstVisibleScrollingRow).GetHeight(newFirstVisibleScrollingRow);
while (deltaY >= height)
{
int scrollingRowTmp = this.Rows.GetPreviousRow(newFirstVisibleScrollingRow,
DataGridViewElementStates.Visible,
DataGridViewElementStates.Frozen);
if (scrollingRowTmp != -1)
{
deltaY -= this.Rows.SharedRow(scrollingRowTmp).GetHeight(scrollingRowTmp);
if (deltaY >= height)
{
newFirstVisibleScrollingRow = scrollingRowTmp;
}
}
else
{
break;
}
}
}
// Tentative target value for this.displayedBandsInfo.FirstDisplayedScrollingRow.
this.displayedBandsInfo.FirstDisplayedScrollingRow = newFirstVisibleScrollingRow;
// This sets the actual value of this.displayedBandsInfo.FirstDisplayedScrollingRow
ComputeVisibleRows();
ScrollEventType scrollEventType = ScrollEventType.EndScroll;
int rowCount = 0;
// Compute the scrollHeight given the new this.displayedBandsInfo.FirstDisplayedScrollingRow
if (this.displayedBandsInfo.FirstDisplayedScrollingRow > oldFirstVisibleScrollingRow)
{
scrollHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible, oldFirstVisibleScrollingRow, this.displayedBandsInfo.FirstDisplayedScrollingRow);
rowCount = this.Rows.GetRowCount(DataGridViewElementStates.Visible, oldFirstVisibleScrollingRow, this.displayedBandsInfo.FirstDisplayedScrollingRow);
scrollEventType = rowCount > 1 ? ScrollEventType.LargeIncrement : ScrollEventType.SmallIncrement;
}
else if (this.displayedBandsInfo.FirstDisplayedScrollingRow < oldFirstVisibleScrollingRow)
{
scrollHeight = -this.Rows.GetRowsHeight(DataGridViewElementStates.Visible, this.displayedBandsInfo.FirstDisplayedScrollingRow, oldFirstVisibleScrollingRow);
rowCount = -this.Rows.GetRowCount(DataGridViewElementStates.Visible, this.displayedBandsInfo.FirstDisplayedScrollingRow, oldFirstVisibleScrollingRow);
scrollEventType = rowCount < -1 ? ScrollEventType.LargeDecrement : ScrollEventType.SmallDecrement;
}
if (scrollHeight != 0)
{
ScrollRows(rowCount, -scrollHeight, scrollEventType);
}
FlushDisplayedChanged();
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.SelectAll"]/*' />
// Does not seem to be a valid fxcop violation report. Contacting fxcop team to double-check.
[SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops")]
public void SelectAll()
{
if (!this.MultiSelect)
{
return;
}
this.inBulkPaintCount++;
this.noDimensionChangeCount++;
this.noSelectionChangeCount++;
try
{
DataGridViewRow dataGridViewRow = null;
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
// Bonjour the scalability issues! We select each cell, one at the time.
int maxColumnIndex = this.Columns.Count;
int rowIndex = 0, maxRowIndex = this.Rows.Count;
while (rowIndex < maxRowIndex)
{
dataGridViewRow = this.Rows[rowIndex]; //unsharing each row!
int columnIndex = 0;
while (columnIndex < maxColumnIndex)
{
SetSelectedCellCore(columnIndex, rowIndex, true);
columnIndex++;
}
rowIndex++;
}
break;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
int rowIndex = 0, maxRowIndex = this.Rows.Count;
while (rowIndex < maxRowIndex)
{
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if ((rowState & DataGridViewElementStates.Selected) == 0)
{
SetSelectedRowCore(rowIndex, true);
}
rowIndex++;
}
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
int columnIndex = 0, maxColumnIndex = this.Columns.Count;
while (columnIndex < maxColumnIndex)
{
if (!this.Columns[columnIndex].Selected)
{
SetSelectedColumnCore(columnIndex, true);
}
columnIndex++;
}
break;
}
}
}
finally
{
this.noDimensionChangeCount--;
this.noSelectionChangeCount--;
Debug.Assert(this.noDimensionChangeCount >= 0);
Debug.Assert(this.noSelectionChangeCount >= 0);
ExitBulkPaint(-1, -1);
}
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (dataGridViewColumn != null && firstVisibleRowIndex != -1)
{
// This is the only place in the code outside of SetCurrentCellAddressCore where this.ptAnchorCell gets changed.
// There is no way in SetCurrentCellAddressCore to just change the anchor cell.
this.ptAnchorCell.X = dataGridViewColumn.Index;
this.ptAnchorCell.Y = firstVisibleRowIndex;
}
else
{
this.ptAnchorCell.X = -1;
this.ptAnchorCell.Y = -1;
}
if (this.noSelectionChangeCount == 0)
{
FlushSelectionChanged();
}
}
private DataGridViewCell SelectedCell(int index)
{
Debug.Assert(index >= 0);
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
if (index < this.individualSelectedCells.Count)
{
return this.individualSelectedCells[index];
}
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
int selectedBand = 0, selectedBands = this.selectedBandIndexes.Count;
while (selectedBand < selectedBands && index >= 0)
{
if (index >= this.Rows.Count)
{
index -= this.Rows.Count;
selectedBand++;
}
else
{
int columnIndex = this.selectedBandIndexes[selectedBand];
return this.Rows.SharedRow(index).Cells[columnIndex];
}
}
if (this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect &&
index < this.individualSelectedCells.Count)
{
return this.individualSelectedCells[index];
}
break;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
int selectedBand = 0, selectedBands = this.selectedBandIndexes.Count;
while (selectedBand < selectedBands && index >= 0)
{
if (index >= this.Columns.Count)
{
index -= this.Columns.Count;
selectedBand++;
}
else
{
int rowIndex = this.selectedBandIndexes[selectedBand];
return this.Rows.SharedRow(rowIndex).Cells[index];
}
}
if (this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect &&
index < this.individualSelectedCells.Count)
{
return this.individualSelectedCells[index];
}
break;
}
}
return null;
}
private void SetColumnHeadersHeightInternal(int columnHeadersHeight, bool invalidInAdjustFillingColumns)
{
using (LayoutTransaction.CreateTransactionIf(this.AutoSize, this.ParentInternal, this, PropertyNames.ColumnHeadersHeight))
{
Debug.Assert(this.columnHeadersHeight != columnHeadersHeight);
Debug.Assert(columnHeadersHeight >= minimumColumnHeadersHeight);
Debug.Assert(columnHeadersHeight <= maxHeadersThickness);
this.columnHeadersHeight = columnHeadersHeight;
if (this.AutoSize)
{
InvalidateInside();
}
else
{
if (this.layout.ColumnHeadersVisible)
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, invalidInAdjustFillingColumns, true /*repositionEditingControl*/);
InvalidateInside();
}
}
OnColumnHeadersHeightChanged(EventArgs.Empty);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.SetCurrentCellAddressCore"]/*' />
protected virtual bool SetCurrentCellAddressCore(int columnIndex,
int rowIndex,
bool setAnchorCellAddress,
bool validateCurrentCell,
bool throughMouseClick)
{
if (columnIndex < -1 ||
(columnIndex >= 0 && rowIndex == -1) ||
columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex < -1 ||
(columnIndex == -1 && rowIndex >= 0) ||
rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex > -1 &&
rowIndex > -1 &&
!IsSharedCellVisible(this.Rows.SharedRow(rowIndex).Cells[columnIndex], rowIndex))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CurrentCellCannotBeInvisible));
}
if (this.dataGridViewOper[DATAGRIDVIEWOPER_inCurrentCellChange] && // Allow the code to be re-entrant only as a result of
(this.dataConnection == null || !this.dataConnection.ProcessingListChangedEvent)) // underlying data changing.
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_SetCurrentCellAddressCoreNotReentrant));
}
this.dataGridViewOper[DATAGRIDVIEWOPER_inCurrentCellChange] = true;
try
{
DataGridViewCell dataGridViewCellTmp = null;
if (columnIndex > -1)
{
Debug.Assert(rowIndex >= 0 &&
columnIndex < this.Columns.Count &&
rowIndex < this.Rows.Count);
if (this.ptCurrentCell.X != columnIndex || this.ptCurrentCell.Y != rowIndex)
{
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell])
{
this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell] = false;
this.ptCurrentCell.X = columnIndex;
this.ptCurrentCell.Y = rowIndex;
if (this.cachedEditingControl != null)
{
this.editingControl = this.cachedEditingControl;
((IDataGridViewEditingControl)this.editingControl).EditingControlRowIndex = rowIndex;
this.cachedEditingControl = null;
PositionEditingControl(true, true, false);
}
OnCurrentCellChanged(EventArgs.Empty);
return true;
}
DataGridViewCell currentCell;
int oldCurrentCellX = this.ptCurrentCell.X;
int oldCurrentCellY = this.ptCurrentCell.Y;
if (oldCurrentCellX >= 0)
{
currentCell = this.CurrentCellInternal;
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.CurrentCellChange,
validateCurrentCell ? DataGridViewValidateCellInternal.Always : DataGridViewValidateCellInternal.Never /*validateCell*/,
validateCurrentCell /*fireCellLeave*/,
false /*fireCellEnter*/,
validateCurrentCell && oldCurrentCellY != rowIndex /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
this.EditMode != DataGridViewEditMode.EditOnEnter /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell unused here*/))
{
return false;
}
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
currentCell = this.Rows.SharedRow(oldCurrentCellY).Cells[oldCurrentCellX];
if (currentCell.LeaveUnsharesRowInternal(oldCurrentCellY, throughMouseClick))
{
currentCell = this.Rows[oldCurrentCellY].Cells[oldCurrentCellX]; // unsharing the current row
}
currentCell.OnLeaveInternal(oldCurrentCellY, throughMouseClick);
}
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
if (oldCurrentCellY != rowIndex)
{
if (validateCurrentCell)
{
if (OnRowValidating(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY))
{
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
// Row validation was cancelled
Debug.Assert(oldCurrentCellX == this.ptCurrentCell.X);
Debug.Assert(oldCurrentCellY == this.ptCurrentCell.Y);
OnRowEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY, true /*canCreateNewRow*/, true /*validationFailureOccurred*/);
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
currentCell.OnEnterInternal(oldCurrentCellY, throughMouseClick);
OnCellEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
}
}
return false;
}
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
OnRowValidated(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
}
}
}
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_rowsCollectionClearedInSetCell] = false;
try
{
if (oldCurrentCellY != rowIndex)
{
//Tentatively commenting out for bug #321924
//this.ptCurrentCell.X = -1;
//this.ptCurrentCell.Y = -1;
//OnCurrentCellChanged(EventArgs.Empty);
if (!IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
OnRowEnter(ref dataGridViewCellTmp, columnIndex, rowIndex, true /*canCreateNewRow*/, false /*validationFailureOccurred*/);
}
}
// Force repainting of the current and previous collumns` header cells to update highlighting
if (oldCurrentCellX != columnIndex &&
this.SelectionMode == DataGridViewSelectionMode.FullRowSelect &&
AccessibilityImprovements.Level2)
{
if (oldCurrentCellX >= 0)
{
InvalidateCellPrivate(oldCurrentCellX, -1);
}
InvalidateCellPrivate(columnIndex, -1);
}
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_rowsCollectionClearedInSetCell])
{
//
// The rows collection was cleared while processing OnRowEnter.
// If the new list is too small for rowIndex, fail the call to SetCurrentCellAddressCore.
//
if (rowIndex >= this.Rows.Count)
{
return false;
}
// rowIndex = Math.Min(rowIndex, this.Rows.GetRowCount(DataGridViewElementStates.Visible) - 1);
}
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
this.ptCurrentCell.X = columnIndex;
this.ptCurrentCell.Y = rowIndex;
if (this.editingControl != null)
{
((IDataGridViewEditingControl)this.editingControl).EditingControlRowIndex = rowIndex;
}
OnCurrentCellChanged(EventArgs.Empty);
if (setAnchorCellAddress)
{
this.ptAnchorCell.X = columnIndex;
this.ptAnchorCell.Y = rowIndex;
}
#if FALSE
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_rowsCollectionClearedInSetCell])
{
// DATAGRIDVIEWSTATE2_rowsCollectionClearedInSetCell bit will be cleared while executing the
// "finally" block.
return true;
}
#endif
currentCell = this.CurrentCellInternal;
if (currentCell.EnterUnsharesRowInternal(rowIndex, throughMouseClick))
{
currentCell = this.Rows[rowIndex].Cells[columnIndex]; // unsharing the row
}
currentCell.OnEnterInternal(rowIndex, throughMouseClick);
OnCellEnter(ref dataGridViewCellTmp, this.ptCurrentCell.X, this.ptCurrentCell.Y);
if (oldCurrentCellX >= 0)
{
Debug.Assert(oldCurrentCellY >= 0);
if (oldCurrentCellX < this.Columns.Count && oldCurrentCellY < this.Rows.Count)
{
InvalidateCellPrivate(oldCurrentCellX, oldCurrentCellY);
}
if (oldCurrentCellY != this.ptCurrentCell.Y && this.RowHeadersVisible && oldCurrentCellY < this.Rows.Count)
{
InvalidateCellPrivate(-1, oldCurrentCellY);
}
}
InvalidateCellPrivate(this.ptCurrentCell.X, this.ptCurrentCell.Y);
if (this.RowHeadersVisible && oldCurrentCellY != this.ptCurrentCell.Y)
{
InvalidateCellPrivate(-1, this.ptCurrentCell.Y);
}
if (this.Focused &&
this.ptCurrentCell.X != -1 &&
!this.IsCurrentCellInEditMode &&
!this.dataGridViewState1[DATAGRIDVIEWSTATE1_leavingWithTabKey] && // don't edit if we're in the process of leaving the grid
!this.dataGridViewState2[DATAGRIDVIEWSTATE2_rowsCollectionClearedInSetCell] && // don't edit if the rows collection changed
(this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && currentCell.EditType == null)))
{
BeginEditInternal(true /*selectAll*/);
}
}
finally
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_rowsCollectionClearedInSetCell] = false;
}
// Accessibility
if (this.ptCurrentCell.X != -1)
{
AccessibilityNotifyCurrentCellChanged(new Point(this.ptCurrentCell.X, this.ptCurrentCell.Y));
}
}
else
{
// this.ptCurrentCell.X == columnIndex && this.ptCurrentCell.Y == rowIndex
// Not trying to change the current cell, but may need to edit it.
if (setAnchorCellAddress)
{
this.ptAnchorCell.X = columnIndex;
this.ptAnchorCell.Y = rowIndex;
}
if (this.Focused &&
(!this.IsCurrentCellInEditMode && (this.EditMode == DataGridViewEditMode.EditOnEnter ||
(this.EditMode != DataGridViewEditMode.EditProgrammatically && this.CurrentCellInternal.EditType == null))))
{
BeginEditInternal(true /*selectAll*/);
}
else
{
CorrectFocus(false /*onlyIfGridHasFocus*/);
}
}
}
else
{
int oldCurrentCellX = this.ptCurrentCell.X;
int oldCurrentCellY = this.ptCurrentCell.Y;
if (oldCurrentCellX >= 0 &&
!this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell] &&
!this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose])
{
DataGridViewCell currentCell = this.CurrentCellInternal;
if (!EndEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.CurrentCellChange,
validateCurrentCell ? DataGridViewValidateCellInternal.Always : DataGridViewValidateCellInternal.Never,
validateCurrentCell /*fireCellLeave*/,
false /*fireCellEnter*/,
validateCurrentCell /*fireRowLeave*/,
false /*fireRowEnter*/,
false /*fireLeave*/,
this.EditMode != DataGridViewEditMode.EditOnEnter /*keepFocus*/,
false /*resetCurrentCell*/,
false /*resetAnchorCell unused here*/))
{
return false;
}
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
currentCell = this.Rows.SharedRow(oldCurrentCellY).Cells[oldCurrentCellX];
if (currentCell.LeaveUnsharesRowInternal(oldCurrentCellY, throughMouseClick))
{
currentCell = this.Rows[oldCurrentCellY].Cells[oldCurrentCellX]; // unsharing the current row
}
currentCell.OnLeaveInternal(oldCurrentCellY, throughMouseClick);
}
if (validateCurrentCell)
{
if (OnRowValidating(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY))
{
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
// Row validation was cancelled
Debug.Assert(oldCurrentCellX == this.ptCurrentCell.X);
Debug.Assert(oldCurrentCellY == this.ptCurrentCell.Y);
OnRowEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY, true /*canCreateNewRow*/, true /*validationFailureOccurred*/);
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
currentCell.OnEnterInternal(oldCurrentCellY, throughMouseClick);
OnCellEnter(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
}
}
return false;
}
if (!IsInnerCellOutOfBounds(oldCurrentCellX, oldCurrentCellY))
{
OnRowValidated(ref dataGridViewCellTmp, oldCurrentCellX, oldCurrentCellY);
}
}
}
if (this.ptCurrentCell.X != -1)
{
this.ptCurrentCell.X = -1;
this.ptCurrentCell.Y = -1;
OnCurrentCellChanged(EventArgs.Empty);
}
if (setAnchorCellAddress)
{
this.ptAnchorCell.X = -1;
this.ptAnchorCell.Y = -1;
}
if (this.dataGridViewState1[DATAGRIDVIEWSTATE1_temporarilyResetCurrentCell])
{
if (this.editingControl != null)
{
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_discardEditingControl])
{
this.dataGridViewState2[DATAGRIDVIEWSTATE2_discardEditingControl] = false;
}
else
{
this.cachedEditingControl = this.editingControl;
}
this.editingControl = null;
}
}
else if (oldCurrentCellX >= 0 && !this.dataGridViewOper[DATAGRIDVIEWOPER_inDispose])
{
Debug.Assert(oldCurrentCellY >= 0);
if (oldCurrentCellX < this.Columns.Count && oldCurrentCellY < this.Rows.Count)
{
InvalidateCellPrivate(oldCurrentCellX, oldCurrentCellY);
}
if (this.RowHeadersVisible && oldCurrentCellY < this.Rows.Count)
{
InvalidateCellPrivate(-1, oldCurrentCellY);
}
}
}
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inCurrentCellChange] = false;
}
return true;
}
internal void SetCurrentCellAddressCoreInternal(int columnIndex,
int rowIndex,
bool setAnchorCellAddress,
bool validateCurrentCell,
bool throughMouseClick)
{
SetCurrentCellAddressCore(columnIndex, rowIndex, setAnchorCellAddress, validateCurrentCell, throughMouseClick);
}
private void SelectCellRange(int columnIndexFrom, int rowIndexFrom, int columnIndexTo, int rowIndexTo, bool select)
{
Debug.Assert(columnIndexFrom >= 0 && columnIndexTo >= 0);
Debug.Assert((this.Columns[columnIndexFrom]).DisplayIndex <= (this.Columns[columnIndexTo]).DisplayIndex);
Debug.Assert(rowIndexFrom >= 0 && rowIndexTo >= 0);
Debug.Assert(rowIndexFrom <= rowIndexTo);
Debug.Assert(this.noSelectionChangeCount > 0);
bool switchedToBulkPaint = false;
if (rowIndexTo - rowIndexFrom > DATAGRIDVIEW_bulkPaintThreshold)
{
// Switch to batch operation
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
// Selection and deselection are done in reverse order for perf. reasons.
if (select)
{
int columnIndex = columnIndexFrom;
do
{
for (int rowIndex = rowIndexFrom; rowIndex <= rowIndexTo; rowIndex++)
{
SetSelectedCellCore(columnIndex, rowIndex, true);
}
if (columnIndex != columnIndexTo)
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[columnIndex],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
columnIndex = dataGridViewColumn.Index;
}
}
while (columnIndex != columnIndexTo);
if (columnIndexFrom != columnIndexTo)
{
for (int rowIndex = rowIndexFrom; rowIndex <= rowIndexTo; rowIndex++)
{
SetSelectedCellCore(columnIndex, rowIndex, true);
}
}
}
else
{
int columnIndex = columnIndexTo;
do
{
for (int rowIndex = rowIndexTo; rowIndex >= rowIndexFrom; rowIndex--)
{
SetSelectedCellCore(columnIndex, rowIndex, false);
}
if (columnIndex != columnIndexFrom)
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[columnIndex],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
columnIndex = dataGridViewColumn.Index;
}
}
while (columnIndex != columnIndexFrom);
if (columnIndexFrom != columnIndexTo)
{
for (int rowIndex = rowIndexTo; rowIndex >= rowIndexFrom; rowIndex--)
{
SetSelectedCellCore(columnIndex, rowIndex, false);
}
}
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
private void SelectCellUnorderedRange(int columnIndexFrom, int rowIndexFrom, int columnIndexTo, int rowIndexTo, bool select)
{
Debug.Assert(this.noSelectionChangeCount > 0);
int columnIndexFromTmp, rowIndexFromTmp, columnIndexToTmp, rowIndexToTmp;
if (this.Columns.DisplayInOrder(columnIndexFrom, columnIndexTo))
{
columnIndexFromTmp = columnIndexFrom;
columnIndexToTmp = columnIndexTo;
}
else
{
columnIndexFromTmp = columnIndexTo;
columnIndexToTmp = columnIndexFrom;
}
if (rowIndexFrom < rowIndexTo)
{
rowIndexFromTmp = rowIndexFrom;
rowIndexToTmp = rowIndexTo;
}
else
{
rowIndexFromTmp = rowIndexTo;
rowIndexToTmp = rowIndexFrom;
}
SelectCellRange(columnIndexFromTmp, rowIndexFromTmp, columnIndexToTmp, rowIndexToTmp, select);
}
private void SelectColumnRange(int columnIndexFrom, int columnIndexTo, bool select)
{
Debug.Assert(columnIndexFrom >= 0 && columnIndexTo >= 0);
Debug.Assert((this.Columns[columnIndexFrom]).DisplayIndex <= (this.Columns[columnIndexTo]).DisplayIndex);
Debug.Assert(this.noSelectionChangeCount > 0);
int columnIndex = columnIndexFrom;
do
{
if (select)
{
if (!this.selectedBandIndexes.Contains(columnIndex))
{
SetSelectedColumnCore(columnIndex, true);
}
}
else
{
Debug.Assert(this.selectedBandIndexes.Contains(columnIndex));
SetSelectedColumnCore(columnIndex, false);
}
if (columnIndex != columnIndexTo)
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[columnIndex],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
columnIndex = dataGridViewColumn.Index;
}
}
while (columnIndex != columnIndexTo);
if (columnIndexFrom != columnIndexTo)
{
if (select)
{
if (!this.selectedBandIndexes.Contains(columnIndexTo))
{
SetSelectedColumnCore(columnIndexTo, true);
}
}
else
{
Debug.Assert(this.selectedBandIndexes.Contains(columnIndexTo));
SetSelectedColumnCore(columnIndexTo, false);
}
}
}
private void SelectRowRange(int rowIndexFrom, int rowIndexTo, bool select)
{
Debug.Assert(rowIndexFrom >= 0 && rowIndexTo >= 0);
Debug.Assert(rowIndexFrom <= rowIndexTo);
Debug.Assert(this.noSelectionChangeCount > 0);
bool switchedToBulkPaint = false;
if (rowIndexTo - rowIndexFrom > DATAGRIDVIEW_bulkPaintThreshold)
{
// Switch to batch operation
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
// Selecting and deselecting rows in reverse order for perf. reasons
if (select)
{
for (int rowIndex = rowIndexFrom; rowIndex <= rowIndexTo; rowIndex++)
{
if ((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Selected) == 0)
{
Debug.Assert(!this.selectedBandIndexes.Contains(rowIndex));
SetSelectedRowCore(rowIndex, true);
}
}
}
else
{
for (int rowIndex = rowIndexTo; rowIndex >= rowIndexFrom; rowIndex--)
{
Debug.Assert(this.selectedBandIndexes.Contains(rowIndex));
SetSelectedRowCore(rowIndex, false);
}
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, -1);
}
}
}
private bool SetAndSelectCurrentCellAddress(int columnIndex,
int rowIndex,
bool setAnchorCellAddress,
bool validateCurrentCell,
bool throughMouseClick,
bool clearSelection,
bool forceCurrentCellSelection)
{
if (!SetCurrentCellAddressCore(columnIndex, rowIndex, setAnchorCellAddress, validateCurrentCell, throughMouseClick))
{
return false;
}
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return false;
}
if (clearSelection)
{
ClearSelection(columnIndex, rowIndex, true /*selectException*/); // we always select the new current cell when clearSelection is true
}
else
{
if (forceCurrentCellSelection)
{
SetSelectedElementCore(columnIndex, rowIndex, true);
}
else
{
if (this.MultiSelect && (this.individualSelectedCells.Count + this.selectedBandIndexes.Count) > 1)
{
return true; // Do not discard the multi-selection
}
if (this.individualSelectedCells.Count == 1)
{
DataGridViewCell dataGridViewCell = this.individualSelectedCells.HeadCell;
if (dataGridViewCell.ColumnIndex != columnIndex || dataGridViewCell.RowIndex != rowIndex)
{
return true;
}
}
else if (this.selectedBandIndexes.Count == 1)
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullColumnSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
if (this.selectedBandIndexes.HeadInt != columnIndex)
{
return true; // Do not change a single selection that does not match the new current cell
}
break;
}
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
{
if (this.selectedBandIndexes.HeadInt != rowIndex)
{
return true; // Do not change a single selection that does not match the new current cell
}
break;
}
}
}
SetSelectedElementCore(columnIndex, rowIndex, true);
}
}
return true;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.SetBoundsCore"]/*' />
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width && width > upperSize) {
throw new ArgumentOutOfRangeException("width", width, SR.GetString(SR.DataGridView_SizeTooLarge, (upperSize).ToString(CultureInfo.CurrentCulture)));
}
if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height && height > upperSize) {
throw new ArgumentOutOfRangeException("height", height, SR.GetString(SR.DataGridView_SizeTooLarge, (upperSize).ToString(CultureInfo.CurrentCulture)));
}
base.SetBoundsCore(x, y, width, height, specified);
}
[
SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops") // Illegitimate report.
]
internal void SetReadOnlyCellCore(int columnIndex, int rowIndex, bool readOnly)
{
Debug.Assert(columnIndex >= 0 && rowIndex >= 0 &&
columnIndex < this.Columns.Count &&
rowIndex < this.Rows.Count);
// cell's readonly state changes
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if (IsSharedCellReadOnly(dataGridViewRow.Cells[columnIndex], rowIndex) != readOnly)
{
DataGridViewCell dataGridViewCell = this.Rows[rowIndex].Cells[columnIndex];
if (readOnly)
{
if ((rowState & DataGridViewElementStates.ReadOnly) == 0 &&
!this.Columns[columnIndex].ReadOnly)
{
this.individualReadOnlyCells.Add(dataGridViewCell);
dataGridViewCell.ReadOnlyInternal = true;
}
}
else
{
if (this.individualReadOnlyCells.Contains(dataGridViewCell))
{
this.individualReadOnlyCells.Remove(dataGridViewCell);
}
else
{
DataGridViewCell dataGridViewCellTmp;
if (this.Columns[columnIndex].ReadOnly)
{
this.Columns[columnIndex].ReadOnlyInternal = false;
// Perf Issue: this unshares all rows!
for (int row = 0; row < rowIndex; row++)
{
dataGridViewCellTmp = this.Rows[row].Cells[columnIndex];
dataGridViewCellTmp.ReadOnlyInternal = true;
this.individualReadOnlyCells.Add(dataGridViewCellTmp);
}
for (int row = rowIndex+1; row < this.Rows.Count; row++)
{
dataGridViewCellTmp = this.Rows[row].Cells[columnIndex];
dataGridViewCellTmp.ReadOnlyInternal = true;
this.individualReadOnlyCells.Add(dataGridViewCellTmp);
}
}
if ((rowState & DataGridViewElementStates.ReadOnly) != 0)
{
this.Rows.SetRowState(rowIndex, DataGridViewElementStates.ReadOnly, false);
for (int column = 0; column < columnIndex; column++)
{
dataGridViewCellTmp = this.Rows[rowIndex].Cells[column];
dataGridViewCellTmp.ReadOnlyInternal = true;
this.individualReadOnlyCells.Add(dataGridViewCellTmp);
}
for (int column = columnIndex+1; column < this.Columns.Count; column++)
{
dataGridViewCellTmp = this.Rows[rowIndex].Cells[column];
dataGridViewCellTmp.ReadOnlyInternal = true;
this.individualReadOnlyCells.Add(dataGridViewCellTmp);
}
}
}
if (dataGridViewCell.ReadOnly)
{
dataGridViewCell.ReadOnlyInternal = false;
}
}
}
}
internal void SetReadOnlyColumnCore(int columnIndex, bool readOnly)
{
Debug.Assert(columnIndex >= 0 && columnIndex < this.Columns.Count);
if (this.Columns[columnIndex].ReadOnly != readOnly)
{
// ReadOnly state of entire column changes
if (readOnly)
{
// column is made read-only
// remove individual read-only cells of this column
try
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange] = true;
RemoveIndividualReadOnlyCellsInColumn(columnIndex);
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange] = false;
}
this.Columns[columnIndex].ReadOnlyInternal = true;
}
else
{
// column is made read-write
this.Columns[columnIndex].ReadOnlyInternal = false;
}
}
else if (!readOnly)
{
// remove any potentially individual read-only cells in the column
RemoveIndividualReadOnlyCellsInColumn(columnIndex);
}
}
internal void SetReadOnlyRowCore(int rowIndex, bool readOnly)
{
Debug.Assert(rowIndex >= 0 && rowIndex < this.Rows.Count);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if (((rowState & DataGridViewElementStates.ReadOnly) != 0) != readOnly)
{
// ReadOnly state of entire row changes
if (readOnly)
{
// row is made read-only
// first remove individual read-only cells of this row
try
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange] = true;
RemoveIndividualReadOnlyCellsInRow(rowIndex);
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inReadOnlyChange] = false;
}
this.Rows.SetRowState(rowIndex, DataGridViewElementStates.ReadOnly, true);
}
else
{
// row is made read-write
this.Rows.SetRowState(rowIndex, DataGridViewElementStates.ReadOnly, false);
}
}
else if (!readOnly)
{
// remove any potentially individual read-only cells in the row
RemoveIndividualReadOnlyCellsInRow(rowIndex);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.SetSelectedCellCore"]/*' />
[
SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops") // Illegitimate report.
]
protected virtual void SetSelectedCellCore(int columnIndex, int rowIndex, bool selected)
{
if (columnIndex < 0 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex < 0 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
// cell selection changes
DataGridViewRow dataGridViewRow = this.Rows.SharedRow(rowIndex);
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if (IsSharedCellSelected(dataGridViewRow.Cells[columnIndex], rowIndex) != selected)
{
DataGridViewCell dataGridViewCell = this.Rows[rowIndex].Cells[columnIndex];
if (selected)
{
if ((rowState & DataGridViewElementStates.Selected) == 0 &&
!this.Columns[columnIndex].Selected)
{
this.individualSelectedCells.Add(dataGridViewCell);
dataGridViewCell.SelectedInternal = true;
}
}
else
{
if ((dataGridViewCell.State & DataGridViewElementStates.Selected) != 0)
{
Debug.Assert(this.individualSelectedCells.Contains(dataGridViewCell));
this.individualSelectedCells.Remove(dataGridViewCell);
}
else
{
DataGridViewCell dataGridViewCellTmp;
bool switchedToBulkPaint = false;
if (this.SelectionMode == DataGridViewSelectionMode.ColumnHeaderSelect)
{
if (this.Rows.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
Debug.Assert(this.selectedBandIndexes.Contains(columnIndex));
this.selectedBandIndexes.Remove(columnIndex);
this.Columns[columnIndex].SelectedInternal = false;
// Perf Issue: this unshares all rows!
for (int row = 0; row < rowIndex; row++)
{
dataGridViewCellTmp = this.Rows[row].Cells[columnIndex];
dataGridViewCellTmp.SelectedInternal = true;
this.individualSelectedCells.Add(dataGridViewCellTmp);
}
for (int row = rowIndex+1; row < this.Rows.Count; row++)
{
dataGridViewCellTmp = this.Rows[row].Cells[columnIndex];
dataGridViewCellTmp.SelectedInternal = true;
this.individualSelectedCells.Add(dataGridViewCellTmp);
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(columnIndex, -1);
}
}
}
else if (this.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect)
{
if (this.Columns.Count > DATAGRIDVIEW_bulkPaintThreshold)
{
this.inBulkPaintCount++;
switchedToBulkPaint = true;
}
try
{
Debug.Assert(this.selectedBandIndexes.Contains(rowIndex));
this.selectedBandIndexes.Remove(rowIndex);
this.Rows.SetRowState(rowIndex, DataGridViewElementStates.Selected, false);
for (int column = 0; column < columnIndex; column++)
{
dataGridViewCellTmp = this.Rows[rowIndex].Cells[column];
dataGridViewCellTmp.SelectedInternal = true;
this.individualSelectedCells.Add(dataGridViewCellTmp);
}
for (int column = columnIndex+1; column < this.Columns.Count; column++)
{
dataGridViewCellTmp = this.Rows[rowIndex].Cells[column];
dataGridViewCellTmp.SelectedInternal = true;
this.individualSelectedCells.Add(dataGridViewCellTmp);
}
}
finally
{
if (switchedToBulkPaint)
{
ExitBulkPaint(-1, rowIndex);
}
}
}
}
if (dataGridViewCell.Selected)
{
dataGridViewCell.SelectedInternal = false;
}
}
}
}
internal void SetSelectedCellCoreInternal(int columnIndex, int rowIndex, bool selected)
{
if (selected && !this.MultiSelect)
{
if (!this.Columns[columnIndex].Visible ||
(this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) == 0)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CurrentCellCannotBeInvisible));
}
if (!ScrollIntoView(columnIndex, rowIndex, true))
{
return;
}
if (IsInnerCellOutOfBounds(columnIndex, rowIndex))
{
return;
}
}
this.noSelectionChangeCount++;
try
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
if (selected && !this.MultiSelect)
{
Debug.Assert(this.individualSelectedCells.Count <= 1);
RemoveIndividuallySelectedCells();
}
SetSelectedCellCore(columnIndex, rowIndex, selected);
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
{
if (selected)
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != columnIndex)
{
// deselect currently selected column
SetSelectedColumnCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
}
if (!this.selectedBandIndexes.Contains(columnIndex))
{
SetSelectedColumnCore(columnIndex, true);
}
}
else
{
if (this.selectedBandIndexes.Contains(columnIndex))
{
SetSelectedColumnCore(columnIndex, false);
}
}
break;
}
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
if (selected)
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedColumnCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
RemoveIndividuallySelectedCells();
}
}
SetSelectedCellCore(columnIndex, rowIndex, true);
}
else
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedColumnCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
SetSelectedCellCore(columnIndex, rowIndex, false);
}
}
else
{
SetSelectedCellCore(columnIndex, rowIndex, false);
}
}
break;
}
case DataGridViewSelectionMode.FullRowSelect:
{
if (selected)
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
int bandIndex = 0;
while (bandIndex < this.selectedBandIndexes.Count)
{
if (this.selectedBandIndexes[bandIndex] != rowIndex)
{
// deselect currently selected row
SetSelectedRowCore(this.selectedBandIndexes[bandIndex], false);
}
else
{
bandIndex++;
}
}
}
if ((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Selected) == 0)
{
Debug.Assert(this.selectedBandIndexes.Contains(rowIndex) ==
((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Selected) != 0));
SetSelectedRowCore(rowIndex, true);
}
}
else
{
if ((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Selected) != 0)
{
Debug.Assert(this.selectedBandIndexes.Contains(rowIndex) ==
((this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Selected) != 0));
SetSelectedRowCore(rowIndex, false);
}
}
break;
}
case DataGridViewSelectionMode.RowHeaderSelect:
{
if (selected)
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedRowCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
RemoveIndividuallySelectedCells();
}
}
SetSelectedCellCore(columnIndex, rowIndex, true);
}
else
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
SetSelectedRowCore(this.selectedBandIndexes.HeadInt, false);
}
else
{
SetSelectedCellCore(columnIndex, rowIndex, false);
}
}
else
{
SetSelectedCellCore(columnIndex, rowIndex, false);
}
}
break;
}
}
}
finally
{
this.NoSelectionChangeCount--;
}
if (selected && !this.MultiSelect)
{
bool success = SetCurrentCellAddressCore(columnIndex, rowIndex, true, false, true);
Debug.Assert(success);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.SetSelectedColumnCore"]/*' />
protected virtual void SetSelectedColumnCore(int columnIndex, bool selected)
{
if (columnIndex < 0 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
this.noSelectionChangeCount++;
try
{
if (this.Columns[columnIndex].Selected != selected)
{
// selection of entire column changes
if (selected)
{
// column is selected
// remove individually selected cells of this column
RemoveIndividuallySelectedCellsInColumn(columnIndex);
this.Columns[columnIndex].SelectedInternal = true;
Debug.Assert(!this.selectedBandIndexes.Contains(columnIndex));
this.selectedBandIndexes.Add(columnIndex);
}
else
{
// column is deselected
Debug.Assert(this.selectedBandIndexes.Contains(columnIndex));
this.Columns[columnIndex].SelectedInternal = false;
this.selectedBandIndexes.Remove(columnIndex);
}
}
else if (!selected)
{
// remove any potentially individually selected cells in the column
RemoveIndividuallySelectedCellsInColumn(columnIndex);
}
}
finally
{
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
this.NoSelectionChangeCount--;
}
}
internal void SetSelectedColumnCoreInternal(int columnIndex, bool selected)
{
this.noSelectionChangeCount++;
try
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
int columnIndexSelected = this.selectedBandIndexes.HeadInt;
if (columnIndexSelected != columnIndex)
{
SetSelectedColumnCore(columnIndexSelected, false);
}
}
}
SetSelectedColumnCore(columnIndex, selected);
}
finally
{
this.NoSelectionChangeCount--;
}
}
private void SetSelectedElementCore(int columnIndex, int rowIndex, bool selected)
{
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
{
SetSelectedCellCore(columnIndex, rowIndex, selected);
break;
}
case DataGridViewSelectionMode.RowHeaderSelect:
{
if (columnIndex == -1)
{
SetSelectedRowCore(rowIndex, selected);
}
else
{
SetSelectedCellCore(columnIndex, rowIndex, selected);
}
break;
}
case DataGridViewSelectionMode.ColumnHeaderSelect:
{
if (rowIndex == -1)
{
SetSelectedColumnCore(columnIndex, selected);
}
else
{
SetSelectedCellCore(columnIndex, rowIndex, selected);
}
break;
}
case DataGridViewSelectionMode.FullRowSelect:
{
SetSelectedRowCore(rowIndex, selected);
break;
}
case DataGridViewSelectionMode.FullColumnSelect:
{
SetSelectedColumnCore(columnIndex, selected);
break;
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.SetSelectedRowCore"]/*' />
protected virtual void SetSelectedRowCore(int rowIndex, bool selected)
{
if (rowIndex < 0 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
this.noSelectionChangeCount++;
try
{
DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
if (((rowState & DataGridViewElementStates.Selected) != 0) != selected)
{
// selection of entire row changes
if (selected)
{
// row is selected
// first remove individually selected cells of this row
RemoveIndividuallySelectedCellsInRow(rowIndex);
Debug.Assert(!this.selectedBandIndexes.Contains(rowIndex));
this.selectedBandIndexes.Add(rowIndex);
this.Rows.SetRowState(rowIndex, DataGridViewElementStates.Selected, true);
}
else
{
// row is deselected
Debug.Assert(this.selectedBandIndexes.Contains(rowIndex));
this.selectedBandIndexes.Remove(rowIndex);
this.Rows.SetRowState(rowIndex, DataGridViewElementStates.Selected, false);
}
}
else if (!selected)
{
// remove any potentially individually selected cells in the row
RemoveIndividuallySelectedCellsInRow(rowIndex);
}
}
finally
{
Debug.Assert(this.MultiSelect || this.selectedBandIndexes.Count <= 1);
this.NoSelectionChangeCount--;
}
}
internal void SetSelectedRowCoreInternal(int rowIndex, bool selected)
{
this.noSelectionChangeCount++;
try
{
if (!this.MultiSelect)
{
Debug.Assert(this.selectedBandIndexes.Count <= 1);
if (this.selectedBandIndexes.Count > 0)
{
int rowIndexSelected = this.selectedBandIndexes.HeadInt;
if (rowIndexSelected != rowIndex)
{
SetSelectedRowCore(rowIndexSelected, false);
}
}
}
SetSelectedRowCore(rowIndex, selected);
}
finally
{
this.NoSelectionChangeCount--;
}
}
private bool ShouldSerializeAlternatingRowsDefaultCellStyle()
{
DataGridViewCellStyle defaultStyle = new DataGridViewCellStyle();
return !this.AlternatingRowsDefaultCellStyle.Equals(defaultStyle);
}
private bool ShouldSerializeColumnHeadersDefaultCellStyle()
{
return !this.ColumnHeadersDefaultCellStyle.Equals(this.DefaultColumnHeadersDefaultCellStyle);
}
private bool ShouldSerializeDefaultCellStyle()
{
return !this.DefaultCellStyle.Equals(this.DefaultDefaultCellStyle);
}
private bool ShouldSerializeRowHeadersDefaultCellStyle()
{
return !this.RowHeadersDefaultCellStyle.Equals(this.DefaultRowHeadersDefaultCellStyle);
}
private bool ShouldSerializeRowsDefaultCellStyle()
{
DataGridViewCellStyle defaultStyle = new DataGridViewCellStyle();
return !this.RowsDefaultCellStyle.Equals(defaultStyle);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.Sort1"]/*' />
public virtual void Sort(DataGridViewColumn dataGridViewColumn, ListSortDirection direction)
{
if (dataGridViewColumn == null)
{
throw new ArgumentNullException("dataGridViewColumn");
}
if (direction != ListSortDirection.Ascending && direction != ListSortDirection.Descending)
{
throw new InvalidEnumArgumentException("direction", (int)direction, typeof(ListSortDirection));
}
if (dataGridViewColumn.DataGridView != this)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnDoesNotBelongToDataGridView));
}
if (this.VirtualMode && !dataGridViewColumn.IsDataBound)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_OperationDisabledInVirtualMode));
}
SortInternal(null, dataGridViewColumn, direction);
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.Sort2"]/*' />
public virtual void Sort(IComparer comparer)
{
if (comparer == null)
{
throw new ArgumentNullException("comparer");
}
if (this.VirtualMode)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_OperationDisabledInVirtualMode));
}
// can't sort a data bound dataGridView control using a comparer
if (this.DataSource != null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotUseAComparerToSortDataGridViewWhenDataBound));
}
SortInternal(comparer, null, ListSortDirection.Ascending);
}
private void SortDataBoundDataGridView_PerformCheck(DataGridViewColumn dataGridViewColumn)
{
IBindingList ibl = this.dataConnection.List as IBindingList;
if (ibl == null)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CannotSortDataBoundDataGridViewBoundToNonIBindingList));
}
if (!ibl.SupportsSorting)
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_IBindingListNeedsToSupportSorting));
}
if (!dataGridViewColumn.IsDataBound)
{
throw new ArgumentException(SR.GetString(SR.DataGridView_ColumnNeedsToBeDataBoundWhenSortingDataBoundDataGridView), "dataGridViewColumn");
}
}
private void SortInternal(IComparer comparer, DataGridViewColumn dataGridViewColumn, ListSortDirection direction)
{
Debug.Assert(!(comparer != null && this.DataSource != null));
Debug.Assert(direction == ListSortDirection.Ascending || direction == ListSortDirection.Descending);
// Exit editing mode if needed
this.ptCurrentCellCache.X = this.ptCurrentCell.X;
this.ptCurrentCellCache.Y = this.ptCurrentCell.Y;
this.dataGridViewOper[DATAGRIDVIEWOPER_inSort] = true;
try
{
if (!SetCurrentCellAddressCore(-1, -1, true, true, false))
{
// Just cancel operation silently instead of throwing InvalidOperationException
// 'finally' below resets this.dataGridViewOper[DATAGRIDVIEWOPER_inSort] to false
return;
}
int firstDisplayedScrollingRowCache = this.displayedBandsInfo.FirstDisplayedScrollingRow;
int visibleFrozenRows = this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
if (visibleFrozenRows > 0 && this.DataSource == null)
{
int rowVFIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
Debug.Assert(rowVFIndex != -1);
this.Rows.SetRowState(rowVFIndex, DataGridViewElementStates.Frozen, false);
Debug.Assert(0 == this.Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen));
}
if (this.sortedColumn != null &&
this.sortedColumn.SortMode == DataGridViewColumnSortMode.Automatic &&
this.sortedColumn.HasHeaderCell)
{
this.sortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
}
if (comparer == null)
{
Debug.Assert(dataGridViewColumn != null);
this.sortedColumn = dataGridViewColumn;
this.sortOrder = (direction == ListSortDirection.Ascending) ? SortOrder.Ascending : SortOrder.Descending;
if (dataGridViewColumn.SortMode == DataGridViewColumnSortMode.Automatic && dataGridViewColumn.HasHeaderCell)
{
dataGridViewColumn.HeaderCell.SortGlyphDirection = this.sortOrder;
}
}
else
{
this.sortedColumn = null;
this.sortOrder = SortOrder.None;
}
if (this.DataSource == null)
{
// Displayed rows may end up all spread out in the final layout.
// So we simply reset their displayed state before the sort.
UpdateRowsDisplayedState(false /*displayed*/);
this.Rows.Sort(comparer, direction == ListSortDirection.Ascending);
}
else
{
SortDataBoundDataGridView_PerformCheck(dataGridViewColumn);
// the check passed, do the sorting
this.dataConnection.Sort(dataGridViewColumn, direction);
}
if (this.ptCurrentCellCache.X != -1)
{
if (!IsInnerCellOutOfBounds(this.ptCurrentCellCache.X, this.ptCurrentCellCache.Y))
{
SetAndSelectCurrentCellAddress(this.ptCurrentCellCache.X,
this.ptCurrentCellCache.Y,
true,
false,
false,
false /*clearSelection*/,
false /*forceCurrentCellSelection*/);
}
}
if (visibleFrozenRows > 0)
{
int rowVIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
Debug.Assert(rowVIndex != -1);
while (visibleFrozenRows > 1)
{
rowVIndex = this.Rows.GetNextRow(rowVIndex, DataGridViewElementStates.Visible);
Debug.Assert(rowVIndex != -1);
visibleFrozenRows--;
}
this.Rows.SetRowState(rowVIndex, DataGridViewElementStates.Frozen, true);
}
this.displayedBandsInfo.FirstDisplayedScrollingRow = firstDisplayedScrollingRowCache;
}
finally
{
Debug.Assert(this.dataGridViewOper[DATAGRIDVIEWOPER_inSort]);
this.dataGridViewOper[DATAGRIDVIEWOPER_inSort] = false;
}
// Same effect as changing a top level cell style
OnGlobalAutoSize();
if (this.DataSource == null)
{
// VSWhidbey 500898. Ensure that the Displayed states get set properly because they were wiped out by UpdateRowsDisplayedState above.
this.displayedBandsInfo.EnsureDirtyState();
}
ResetUIState(false /*useRowShortcut*/, false /*computeVisibleRows*/);
OnSorted(EventArgs.Empty);
if (AccessibilityImprovements.Level3)
{
// RS4 narrator does not catch this event even though event is indeed raised.
AccessibilityNotifyClients(AccessibleEvents.Reorder, NativeMethods.OBJID_CLIENT, 0);
}
}
internal void SwapSortedRows(int rowIndex1, int rowIndex2)
{
Debug.Assert(rowIndex1 != this.newRowIndex);
Debug.Assert(rowIndex2 != this.newRowIndex);
if (rowIndex1 == rowIndex2)
{
return;
}
// Follow the move of the old current cell
if (rowIndex1 == this.ptCurrentCellCache.Y)
{
this.ptCurrentCellCache.Y = rowIndex2;
}
else if (rowIndex2 == this.ptCurrentCellCache.Y)
{
this.ptCurrentCellCache.Y = rowIndex1;
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.FullRowSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
int row1Selected = this.selectedBandIndexes.IndexOf(rowIndex1);
int row2Selected = this.selectedBandIndexes.IndexOf(rowIndex2);
if (row1Selected != -1 && row2Selected == -1)
{
this.selectedBandIndexes[row1Selected] = rowIndex2;
}
else if (row1Selected == -1 && row2Selected != -1)
{
this.selectedBandIndexes[row2Selected] = rowIndex1;
}
if (this.selectedBandSnapshotIndexes != null)
{
row1Selected = this.selectedBandSnapshotIndexes.IndexOf(rowIndex1);
row2Selected = this.selectedBandSnapshotIndexes.IndexOf(rowIndex2);
if (row1Selected != -1 && row2Selected == -1)
{
this.selectedBandSnapshotIndexes[row1Selected] = rowIndex2;
}
else if (row1Selected == -1 && row2Selected != -1)
{
this.selectedBandSnapshotIndexes[row2Selected] = rowIndex1;
}
}
break;
}
}
private void DataGridViewHScrolled(object sender, ScrollEventArgs se)
{
if (!this.Enabled)
{
return;
}
/* VS Whidbey bug 262445 - no more commit on scroll
if (this.ptCurrentCell.X >= 0)
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinHScroll])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinHScroll] = (se.Type == ScrollEventType.ThumbTrack || se.Type == ScrollEventType.ThumbPosition);
se.NewValue = this.HorizontalOffset;
return;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinHScroll] = (se.Type == ScrollEventType.ThumbTrack || se.Type == ScrollEventType.ThumbPosition);
this.horizScrollBar.Invalidate();
if (!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
false /*forCurrentCellChange-/, false /*forCurrentRowChange-/))
{
se.NewValue = this.HorizontalOffset;
if (se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.SmallDecrement)
{
// Workaround for a pbm where the scrollbar ends up in a bad state after a validation failure dialog is displayed.
this.horizScrollBar.RecreateScrollBarHandle();
}
else
{
this.horizScrollBar.Invalidate();
}
return;
}
else
{
this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinHScroll] = false;
}
}
*/
if (se.Type == ScrollEventType.SmallIncrement ||
se.Type == ScrollEventType.SmallDecrement)
{
int dCols = (se.Type == ScrollEventType.SmallIncrement) ? 1 : -1;
ScrollColumns(dCols);
se.NewValue = this.HorizontalOffset;
}
else if (se.Type != ScrollEventType.EndScroll)
{
this.HorizontalOffset = se.NewValue;
}
}
private void DataGridViewVScrolled(object sender, ScrollEventArgs se)
{
if (!this.Enabled)
{
return;
}
/* VS Whidbey bug 262445 - no more commit on scroll
if (this.ptCurrentCell.X >= 0)
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinVScroll])
{
this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinVScroll] = (se.Type == ScrollEventType.ThumbTrack || se.Type == ScrollEventType.ThumbPosition);
se.NewValue = this.VerticalOffset;
return;
}
this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinVScroll] = (se.Type == ScrollEventType.ThumbTrack || se.Type == ScrollEventType.ThumbPosition);
this.vertScrollBar.Invalidate();
if (!CommitEdit(DataGridViewDataErrorContexts.Parsing | DataGridViewDataErrorContexts.Commit | DataGridViewDataErrorContexts.Scroll,
false /*forCurrentCellChange-/, false /*forCurrentRowChange-/))
{
se.NewValue = this.VerticalOffset;
if (se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.SmallDecrement)
{
// Workaround for a pbm where the scrollbar ends up in a bad state after a validation failure dialog is displayed.
this.vertScrollBar.RecreateScrollBarHandle();
}
else
{
this.vertScrollBar.Invalidate();
}
return;
}
else
{
this.dataGridViewOper[DATAGRIDVIEWOPER_cancelCommitWithinVScroll] = false;
}
}
*/
int totalVisibleFrozenHeight = this.Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
switch (se.Type)
{
case ScrollEventType.SmallIncrement:
{
// Making sure that when the last visible scrolling row is taller than the data area, it does not get scrolled off screen
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
if (this.vertScrollBar.Value + this.Rows.SharedRow(this.displayedBandsInfo.FirstDisplayedScrollingRow).GetHeight(this.displayedBandsInfo.FirstDisplayedScrollingRow) <=
this.vertScrollBar.Maximum - ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight))
{
ScrollRowsByCount(1, ScrollEventType.SmallIncrement);
}
se.NewValue = this.VerticalOffset;
break;
}
case ScrollEventType.SmallDecrement:
{
if (this.vertScrollBar.Value != this.vertScrollBar.Minimum)
{
ScrollRowsByCount(-1, ScrollEventType.SmallDecrement);
}
se.NewValue = this.VerticalOffset;
break;
}
case ScrollEventType.LargeIncrement:
{
Debug.Assert(this.displayedBandsInfo.FirstDisplayedScrollingRow >= 0);
int firstDisplayedScrollingRowHeight = this.Rows.SharedRow(this.displayedBandsInfo.FirstDisplayedScrollingRow).GetHeight(this.displayedBandsInfo.FirstDisplayedScrollingRow);
this.VerticalOffset += Math.Max(firstDisplayedScrollingRowHeight, this.vertScrollBar.LargeChange);
se.NewValue = this.VerticalOffset;
break;
}
case ScrollEventType.LargeDecrement:
{
this.VerticalOffset -= this.vertScrollBar.LargeChange;
se.NewValue = this.VerticalOffset;
break;
}
case ScrollEventType.ThumbTrack:
case ScrollEventType.First:
case ScrollEventType.Last:
{
if (se.NewValue >= this.vertScrollBar.Maximum - this.vertScrollBar.LargeChange)
{
// Need to display the last scrolling row
this.VerticalOffset = this.vertScrollBar.Maximum - ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight);
}
else
{
this.VerticalOffset = se.NewValue;
}
break;
}
}
}
private bool TabToNextCell()
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (firstVisibleColumnIndex == -1 || firstVisibleRowIndex == -1)
{
return false;
}
int nextVisibleColumnIndex = -1;
if (this.ptCurrentCell.X != -1)
{
dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[this.ptCurrentCell.X],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumn != null)
{
nextVisibleColumnIndex = dataGridViewColumn.Index;
}
}
int nextVisibleRowIndex = -1;
if (this.ptCurrentCell.Y != -1)
{
nextVisibleRowIndex = this.Rows.GetNextRow(this.ptCurrentCell.Y, DataGridViewElementStates.Visible);
}
int targetRowIndex = -1, targetColumnIndex = -1;
this.noSelectionChangeCount++;
try
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
}
else
{
if (nextVisibleColumnIndex == -1)
{
targetRowIndex = (nextVisibleRowIndex == -1) ? firstVisibleRowIndex : nextVisibleRowIndex;
targetColumnIndex = firstVisibleColumnIndex;
}
else
{
targetRowIndex = this.ptCurrentCell.Y;
targetColumnIndex = nextVisibleColumnIndex;
}
if (!ScrollIntoView(targetColumnIndex, targetRowIndex, true))
{
return true;
}
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
if (this.ptCurrentCell.X == -1)
{
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
}
else
{
if (IsInnerCellOutOfBounds(targetColumnIndex, targetRowIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(targetColumnIndex, targetRowIndex, true);
}
break;
case DataGridViewSelectionMode.FullColumnSelect:
if (this.ptCurrentCell.X == -1)
{
if (IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
SetSelectedColumnCore(firstVisibleColumnIndex, true);
}
else
{
if (IsColumnOutOfBounds(targetColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedColumnCore(targetColumnIndex, true);
}
break;
case DataGridViewSelectionMode.FullRowSelect:
if (this.ptCurrentCell.X == -1)
{
if (IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
SetSelectedRowCore(firstVisibleRowIndex, true);
}
else
{
if (targetRowIndex != this.ptCurrentCell.Y || this.MultiSelect)
{
if (IsRowOutOfBounds(targetRowIndex))
{
return true;
}
ClearSelection();
SetSelectedRowCore(targetRowIndex, true);
}
}
break;
}
}
finally
{
this.NoSelectionChangeCount--;
}
if (this.ptCurrentCell.X == -1)
{
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
}
else
{
if (IsInnerCellOutOfBounds(targetColumnIndex, targetRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(targetColumnIndex, targetRowIndex, true, false, false);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
}
return true;
}
private bool TabToPreviousCell()
{
bool success;
DataGridViewColumn dataGridViewColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
int firstVisibleColumnIndex = (dataGridViewColumn == null) ? -1 : dataGridViewColumn.Index;
int firstVisibleRowIndex = this.Rows.GetFirstRow(DataGridViewElementStates.Visible);
if (firstVisibleColumnIndex == -1 || firstVisibleRowIndex == -1)
{
return false;
}
int previousVisibleColumnIndex = -1;
if (this.ptCurrentCell.X != -1)
{
dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[this.ptCurrentCell.X],
DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
if (dataGridViewColumn != null)
{
previousVisibleColumnIndex = dataGridViewColumn.Index;
}
}
int previousVisibleRowIndex = -1;
if (this.ptCurrentCell.Y != -1)
{
previousVisibleRowIndex = this.Rows.GetPreviousRow(this.ptCurrentCell.Y, DataGridViewElementStates.Visible);
}
dataGridViewColumn = this.Columns.GetLastColumn(DataGridViewElementStates.Visible,
DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
int lastVisibleColumnIndex = dataGridViewColumn.Index;
int lastVisibleRowIndex = this.Rows.GetLastRow(DataGridViewElementStates.Visible);
Debug.Assert(lastVisibleRowIndex != -1);
int targetRowIndex = -1, targetColumnIndex = -1;
this.noSelectionChangeCount++;
try
{
if (this.ptCurrentCell.X == -1)
{
ClearSelection();
}
else
{
if (previousVisibleColumnIndex == -1)
{
targetRowIndex = (previousVisibleRowIndex == -1) ? lastVisibleRowIndex : previousVisibleRowIndex;
targetColumnIndex = lastVisibleColumnIndex;
}
else
{
targetRowIndex = this.ptCurrentCell.Y;
targetColumnIndex = previousVisibleColumnIndex;
}
if (!ScrollIntoView(targetColumnIndex, targetRowIndex, true))
{
return true;
}
}
switch (this.SelectionMode)
{
case DataGridViewSelectionMode.CellSelect:
case DataGridViewSelectionMode.RowHeaderSelect:
case DataGridViewSelectionMode.ColumnHeaderSelect:
if (this.ptCurrentCell.X == -1)
{
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
SetSelectedCellCore(firstVisibleColumnIndex, firstVisibleRowIndex, true);
}
else
{
if (IsInnerCellOutOfBounds(targetColumnIndex, targetRowIndex))
{
return true;
}
ClearSelection();
SetSelectedCellCore(targetColumnIndex, targetRowIndex, true);
}
break;
case DataGridViewSelectionMode.FullColumnSelect:
if (this.ptCurrentCell.X == -1)
{
if (IsColumnOutOfBounds(firstVisibleColumnIndex))
{
return true;
}
SetSelectedColumnCore(firstVisibleColumnIndex, true);
}
else
{
if (IsColumnOutOfBounds(targetColumnIndex))
{
return true;
}
ClearSelection();
SetSelectedColumnCore(targetColumnIndex, true);
}
break;
case DataGridViewSelectionMode.FullRowSelect:
if (this.ptCurrentCell.X == -1)
{
if (IsRowOutOfBounds(firstVisibleRowIndex))
{
return true;
}
SetSelectedRowCore(firstVisibleRowIndex, true);
}
else
{
if (targetRowIndex != this.ptCurrentCell.Y || this.MultiSelect)
{
if (IsRowOutOfBounds(targetRowIndex))
{
return true;
}
ClearSelection();
SetSelectedRowCore(targetRowIndex, true);
}
}
break;
}
}
finally
{
this.NoSelectionChangeCount--;
}
if (this.ptCurrentCell.X == -1)
{
success = ScrollIntoView(firstVisibleColumnIndex, firstVisibleRowIndex, false);
Debug.Assert(success);
if (IsInnerCellOutOfBounds(firstVisibleColumnIndex, firstVisibleRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(firstVisibleColumnIndex, firstVisibleRowIndex, true, false, false);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
}
else
{
if (IsInnerCellOutOfBounds(targetColumnIndex, targetRowIndex))
{
return true;
}
success = SetCurrentCellAddressCore(targetColumnIndex, targetRowIndex, true, false, false);
// Microsoft: SetCurrentCellAddressCore can fail if by navigating to a cell the list under the
// DataGridView changes.
// See vsWhidbey: 325296.
// Debug.Assert(success);
}
return true;
}
private void UnwireEditingControlEvents()
{
Debug.Assert(this.editingPanel != null);
this.editingPanel.Click -= new System.EventHandler(EditingControls_Click);
this.editingPanel.DoubleClick -= new System.EventHandler(EditingControls_DoubleClick);
this.editingPanel.MouseClick -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseClick);
this.editingPanel.MouseDoubleClick -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDoubleClick);
this.editingPanel.MouseDown -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDown);
this.editingPanel.MouseEnter -= new System.EventHandler(EditingControls_MouseEnter);
this.editingPanel.MouseLeave -= new System.EventHandler(EditingControls_MouseLeave);
this.editingPanel.MouseMove -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseMove);
this.editingPanel.MouseUp -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseUp);
Debug.Assert(this.editingControl != null);
this.editingControl.Click -= new System.EventHandler(EditingControls_Click);
this.editingControl.DoubleClick -= new System.EventHandler(EditingControls_DoubleClick);
this.editingControl.MouseClick -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseClick);
this.editingControl.MouseDoubleClick -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDoubleClick);
this.editingControl.MouseDown -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDown);
this.editingControl.MouseEnter -= new System.EventHandler(EditingControls_MouseEnter);
this.editingControl.MouseLeave -= new System.EventHandler(EditingControls_MouseLeave);
this.editingControl.MouseMove -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseMove);
this.editingControl.MouseUp -= new System.Windows.Forms.MouseEventHandler(EditingControls_MouseUp);
}
private void UnwireScrollBarsEvents()
{
if (this.horizScrollBar != null)
{
this.horizScrollBar.MouseEnter -= new System.EventHandler(ScrollBar_MouseEnter);
this.horizScrollBar.MouseLeave -= new System.EventHandler(ScrollBar_MouseLeave);
}
if (this.vertScrollBar != null)
{
this.vertScrollBar.MouseEnter -= new System.EventHandler(ScrollBar_MouseEnter);
this.vertScrollBar.MouseLeave -= new System.EventHandler(ScrollBar_MouseLeave);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.UpdateCellErrorText"]/*' />
public void UpdateCellErrorText(int columnIndex, int rowIndex)
{
if (columnIndex < -1 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex < -1 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (this.IsHandleCreated)
{
InvalidateCellPrivate(columnIndex, rowIndex);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.UpdateCellValue"]/*' />
public void UpdateCellValue(int columnIndex, int rowIndex)
{
if (columnIndex < 0 || columnIndex >= this.Columns.Count)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex < 0 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (this.IsHandleCreated)
{
OnCellCommonChange(columnIndex, rowIndex);
}
}
private void UpdateColumnsDisplayedState(bool displayed)
{
// Make sure all displayed frozen columns have their Displayed state set to this.Visible
DataGridViewColumn dataGridViewColumnTmp;
int numDisplayedFrozenCols = this.displayedBandsInfo.NumDisplayedFrozenCols;
if (numDisplayedFrozenCols > 0)
{
dataGridViewColumnTmp = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (numDisplayedFrozenCols > 0)
{
Debug.Assert(dataGridViewColumnTmp != null);
if (dataGridViewColumnTmp.Displayed != displayed)
{
dataGridViewColumnTmp.DisplayedInternal = displayed;
Debug.Assert(ColumnNeedsDisplayedState(dataGridViewColumnTmp));
}
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen, DataGridViewElementStates.None);
numDisplayedFrozenCols--;
}
}
// Make sure all displayed scrolling columns have the Displayed state set to this.Visible
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 != displayed)
{
dataGridViewColumnTmp.DisplayedInternal = displayed;
Debug.Assert(ColumnNeedsDisplayedState(dataGridViewColumnTmp));
}
dataGridViewColumnTmp = this.Columns.GetNextColumn(dataGridViewColumnTmp, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
numDisplayedScrollingCols--;
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.UpdateRowErrorText"]/*' />
public void UpdateRowErrorText(int rowIndex)
{
if (rowIndex < 0 || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (this.IsHandleCreated && this.layout.RowHeadersVisible)
{
InvalidateCellPrivate(-1, rowIndex);
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.UpdateRowErrorText1"]/*' />
public void UpdateRowErrorText(int rowIndexStart, int rowIndexEnd)
{
if (rowIndexStart < 0 || rowIndexStart >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndexStart");
}
if (rowIndexEnd < 0 || rowIndexEnd >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndexEnd");
}
if (rowIndexEnd < rowIndexStart)
{
throw new ArgumentOutOfRangeException("rowIndexEnd");
}
if (this.IsHandleCreated && this.layout.RowHeadersVisible)
{
Rectangle rectUpper = GetCellAdjustedDisplayRectangle(-1, rowIndexStart, true);
Rectangle rectLower = GetCellAdjustedDisplayRectangle(-1, rowIndexEnd, true);
if (rectUpper.IsEmpty || rectLower.IsEmpty)
{
if (!rectUpper.IsEmpty || !rectLower.IsEmpty)
{
Invalidate(this.layout.RowHeaders);
}
}
else
{
Invalidate(Rectangle.Union(rectUpper, rectLower));
}
}
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.UpdateRowHeightInfo"]/*' />
public void UpdateRowHeightInfo(int rowIndex, bool updateToEnd)
{
UpdateRowHeightInfoPrivate(rowIndex, updateToEnd, true /*invalidInAdjustFillingColumns*/);
}
private void UpdateRowHeightInfoPrivate(int rowIndex, bool updateToEnd, bool invalidInAdjustFillingColumns)
{
if ((updateToEnd && rowIndex < 0) || (!updateToEnd && rowIndex < -1) || rowIndex >= this.Rows.Count)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
this.Rows.InvalidateCachedRowsHeights();
bool rowVisible = (rowIndex >= 0 && (this.Rows.GetRowState(rowIndex) & DataGridViewElementStates.Visible) != 0);
// don't do any layout logic if the handled was not created already
if (this.IsHandleCreated && (rowIndex == -1 || rowVisible))
{
if (updateToEnd)
{
int oldFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
if (this.AutoSize)
{
LayoutTransaction.DoLayout(this.ParentInternal, this, PropertyNames.Rows);
}
else
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, invalidInAdjustFillingColumns, false /*repositionEditingControl*/);
}
Rectangle bottomArea = this.layout.Data;
if (this.layout.RowHeadersVisible)
{
bottomArea = Rectangle.Union(bottomArea, this.layout.RowHeaders);
}
else if (this.SingleVerticalBorderAdded)
{
if (!this.RightToLeftInternal)
{
bottomArea.X--;
}
bottomArea.Width++;
}
if (!rowVisible)
{
rowIndex = this.Rows.GetNextRow(rowIndex, DataGridViewElementStates.Visible);
}
if (rowIndex != -1)
{
int topEdge = GetRowYFromIndex(oldFirstVisibleScrollingRow == this.displayedBandsInfo.FirstDisplayedScrollingRow ? rowIndex : this.displayedBandsInfo.FirstDisplayedScrollingRow);
bottomArea.Height -= bottomArea.Y - topEdge;
bottomArea.Y = topEdge;
Invalidate(bottomArea);
}
if (this.editingControl != null)
{
PositionEditingControl(true /*setLocation*/, true /*setSize*/, false /*setFocus*/);
}
}
else
{
if (rowIndex == -1)
{
if (this.AutoSize)
{
LayoutTransaction.DoLayout(this.ParentInternal, this, PropertyNames.Rows);
}
else
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, invalidInAdjustFillingColumns, false /*repositionEditingControl*/);
}
Invalidate();
}
else
{
Debug.Assert(rowVisible);
int oldFirstVisibleScrollingRow = this.displayedBandsInfo.FirstDisplayedScrollingRow;
if (this.inBulkLayoutCount == 0)
{
if (this.AutoSize)
{
LayoutTransaction.DoLayout(this.ParentInternal, this, PropertyNames.Rows);
}
else
{
PerformLayoutPrivate(false /*useRowShortcut*/, false /*computeVisibleRows*/, invalidInAdjustFillingColumns, false /*repositionEditingControl*/);
}
}
if (this.inBulkPaintCount == 0)
{
Rectangle bottomArea = this.layout.Data;
if (this.layout.RowHeadersVisible)
{
bottomArea = Rectangle.Union(bottomArea, this.layout.RowHeaders);
}
else if (this.SingleVerticalBorderAdded)
{
if (!this.RightToLeftInternal)
{
bottomArea.X--;
}
bottomArea.Width++;
}
int topEdge = GetRowYFromIndex(oldFirstVisibleScrollingRow == this.displayedBandsInfo.FirstDisplayedScrollingRow ? rowIndex : this.displayedBandsInfo.FirstDisplayedScrollingRow);
bottomArea.Height -= bottomArea.Y - topEdge;
bottomArea.Y = topEdge;
Invalidate(bottomArea);
}
}
if (this.editingControl != null)
{
PositionEditingControl(rowIndex == -1 || this.ptCurrentCell.Y != rowIndex, true, false);
}
}
UpdateMouseEnteredCell(null /*HitTestInfo*/, null /*MouseEventArgs*/);
}
}
private void UpdateRowsDisplayedState(bool displayed)
{
// Make sure all displayed frozen rows have their Displayed state set to 'displayed'
int rowIndexTmp, numDisplayedFrozenRows = this.displayedBandsInfo.NumDisplayedFrozenRows;
if (numDisplayedFrozenRows > 0)
{
rowIndexTmp = this.Rows.GetFirstRow(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
while (numDisplayedFrozenRows > 0)
{
Debug.Assert(rowIndexTmp != -1);
if (((this.Rows.GetRowState(rowIndexTmp) & DataGridViewElementStates.Displayed) == 0) == displayed)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, displayed);
}
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
numDisplayedFrozenRows--;
}
}
// Make sure all displayed scrolling rows have their Displayed state set to 'displayed'
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) == displayed)
{
this.Rows.SetRowState(rowIndexTmp, DataGridViewElementStates.Displayed, displayed);
}
rowIndexTmp = this.Rows.GetNextRow(rowIndexTmp, DataGridViewElementStates.Visible);
numDisplayedScrollingRows--;
}
}
}
private void UpdateMouseEnteredCell(HitTestInfo hti, MouseEventArgs e)
{
Point ptMouse = PointToClient(Control.MousePosition);
HitTestInfo htiToUse;
if (hti != null)
{
htiToUse = hti;
}
else
{
htiToUse = HitTest(ptMouse.X, ptMouse.Y);
}
if (htiToUse.Type != DataGridViewHitTestType.None &&
htiToUse.Type != DataGridViewHitTestType.HorizontalScrollBar &&
htiToUse.Type != DataGridViewHitTestType.VerticalScrollBar)
{
if (this.ptMouseEnteredCell.X != htiToUse.col || this.ptMouseEnteredCell.Y != htiToUse.row)
{
DataGridViewCellEventArgs dgvce;
if (this.ptMouseEnteredCell.X >= -1 &&
this.ptMouseEnteredCell.X < this.Columns.Count &&
this.ptMouseEnteredCell.Y >= -1 &&
this.ptMouseEnteredCell.Y < this.Rows.Count)
{
dgvce = new DataGridViewCellEventArgs(this.ptMouseEnteredCell.X, this.ptMouseEnteredCell.Y);
OnCellMouseLeave(dgvce);
}
dgvce = new DataGridViewCellEventArgs(htiToUse.col, htiToUse.row);
OnCellMouseEnter(dgvce);
}
if (e != null)
{
int mouseX = e.X - htiToUse.ColumnX;
if (this.RightToLeftInternal)
{
mouseX += ((htiToUse.col == -1) ? this.RowHeadersWidth : this.Columns[htiToUse.col].Thickness);
}
DataGridViewCellMouseEventArgs dgvcme = new DataGridViewCellMouseEventArgs(htiToUse.col, htiToUse.row, mouseX, e.Y - htiToUse.RowY, e);
OnCellMouseMove(dgvcme);
}
}
else if (this.ptMouseEnteredCell.X != -2)
{
if (this.ptMouseEnteredCell.X >= -1 &&
this.ptMouseEnteredCell.X < this.Columns.Count &&
this.ptMouseEnteredCell.Y >= -1 &&
this.ptMouseEnteredCell.Y < this.Rows.Count)
{
DataGridViewCellEventArgs dgvce = new DataGridViewCellEventArgs(this.ptMouseEnteredCell.X, this.ptMouseEnteredCell.Y);
OnCellMouseLeave(dgvce);
}
else
{
this.ptMouseEnteredCell.X = this.ptMouseEnteredCell.Y = -2;
}
}
}
private void UpdateSelectedCellsBlock(int anchorColumnIndex, ref int oldEdgeColumnIndex, int newEdgeColumnIndex,
int anchorRowIndex, ref int oldEdgeRowIndex, int newEdgeRowIndex)
{
Debug.Assert(anchorColumnIndex >= 0);
Debug.Assert(anchorRowIndex >= 0);
Debug.Assert(newEdgeColumnIndex >= 0);
Debug.Assert(newEdgeRowIndex >= 0);
Debug.Assert(this.noSelectionChangeCount > 0);
if ((this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex) &&
this.Columns.DisplayInOrder(newEdgeColumnIndex, anchorColumnIndex)) ||
(this.Columns.DisplayInOrder(oldEdgeColumnIndex, anchorColumnIndex) &&
this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex)) ||
(anchorRowIndex < oldEdgeRowIndex && newEdgeRowIndex < anchorRowIndex) ||
(oldEdgeRowIndex < anchorRowIndex && anchorRowIndex < newEdgeRowIndex))
{
// deselecting all selected block
SelectCellUnorderedRange(anchorColumnIndex, anchorRowIndex, oldEdgeColumnIndex, oldEdgeRowIndex, false);
// and reselecting new block
SelectCellUnorderedRange(anchorColumnIndex, anchorRowIndex, newEdgeColumnIndex, newEdgeRowIndex, true);
oldEdgeColumnIndex = newEdgeColumnIndex;
oldEdgeRowIndex = newEdgeRowIndex;
return;
}
if (this.Columns.DisplayInOrder(oldEdgeColumnIndex, newEdgeColumnIndex) &&
(this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex) || anchorColumnIndex == oldEdgeColumnIndex) &&
oldEdgeRowIndex == newEdgeRowIndex)
{
// h1
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
if (anchorRowIndex <= newEdgeRowIndex)
{
SelectCellRange(dataGridViewColumn.Index, anchorRowIndex, newEdgeColumnIndex, newEdgeRowIndex, true);
}
else
{
// newEdgeRowIndex < anchorRowIndex
SelectCellRange(dataGridViewColumn.Index, newEdgeRowIndex, newEdgeColumnIndex, anchorRowIndex, true);
}
}
else if (this.Columns.DisplayInOrder(newEdgeColumnIndex, oldEdgeColumnIndex) &&
(this.Columns.DisplayInOrder(oldEdgeColumnIndex, anchorColumnIndex) || oldEdgeColumnIndex == anchorColumnIndex) &&
oldEdgeRowIndex == newEdgeRowIndex)
{
// h2
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
if (anchorRowIndex <= newEdgeRowIndex)
{
SelectCellRange(newEdgeColumnIndex, anchorRowIndex, dataGridViewColumn.Index, newEdgeRowIndex, true);
}
else
{
// newEdgeRowIndex < anchorRowIndex
SelectCellRange(newEdgeColumnIndex, newEdgeRowIndex, dataGridViewColumn.Index, anchorRowIndex, true);
}
}
else if (newEdgeRowIndex > oldEdgeRowIndex &&
anchorRowIndex <= oldEdgeRowIndex &&
newEdgeColumnIndex == oldEdgeColumnIndex)
{
// h3
if (this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex) || anchorColumnIndex == newEdgeColumnIndex)
{
SelectCellRange(anchorColumnIndex,
this.Rows.GetNextRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
newEdgeColumnIndex,
newEdgeRowIndex,
true);
}
else
{
// newEdgeColumnIndex before anchorColumnIndex
SelectCellRange(newEdgeColumnIndex,
this.Rows.GetNextRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
anchorColumnIndex,
newEdgeRowIndex,
true);
}
}
else if (newEdgeRowIndex < oldEdgeRowIndex &&
oldEdgeRowIndex <= anchorRowIndex &&
newEdgeColumnIndex == oldEdgeColumnIndex)
{
// h4
if (this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex) || anchorColumnIndex == newEdgeColumnIndex)
{
SelectCellRange(anchorColumnIndex,
newEdgeRowIndex,
newEdgeColumnIndex,
this.Rows.GetPreviousRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
true);
}
else
{
// newEdgeColumnIndex before anchorColumnIndex
SelectCellRange(newEdgeColumnIndex,
newEdgeRowIndex,
anchorColumnIndex,
this.Rows.GetPreviousRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
true);
}
}
else if (this.Columns.DisplayInOrder(oldEdgeColumnIndex, newEdgeColumnIndex) &&
!this.Columns.DisplayInOrder(oldEdgeColumnIndex, anchorColumnIndex) &&
newEdgeRowIndex > oldEdgeRowIndex && anchorRowIndex <= oldEdgeRowIndex)
{
// h5
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(dataGridViewColumn.Index, anchorRowIndex, newEdgeColumnIndex, oldEdgeRowIndex, true);
SelectCellRange(anchorColumnIndex,
this.Rows.GetNextRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
newEdgeColumnIndex,
newEdgeRowIndex,
true);
}
else if (this.Columns.DisplayInOrder(oldEdgeColumnIndex, newEdgeColumnIndex) &&
newEdgeRowIndex < oldEdgeRowIndex && oldEdgeRowIndex <= anchorRowIndex)
{
if (!this.Columns.DisplayInOrder(oldEdgeColumnIndex, anchorColumnIndex))
{
// h6
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(dataGridViewColumn.Index, oldEdgeRowIndex, newEdgeColumnIndex, anchorRowIndex, true);
SelectCellRange(anchorColumnIndex,
newEdgeRowIndex,
newEdgeColumnIndex,
this.Rows.GetPreviousRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
true);
}
else
{
if (!this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex))
{
if (anchorRowIndex == oldEdgeRowIndex)
{
// g2
SelectCellRange(oldEdgeColumnIndex, anchorRowIndex, anchorColumnIndex, oldEdgeRowIndex, false);
SelectCellRange(newEdgeColumnIndex, newEdgeRowIndex, anchorColumnIndex, anchorRowIndex, true);
}
else
{
// b4
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[newEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(oldEdgeRowIndex < anchorRowIndex);
SelectCellRange(oldEdgeColumnIndex, oldEdgeRowIndex, dataGridViewColumn.Index, anchorRowIndex, false);
SelectCellRange(newEdgeColumnIndex,
newEdgeRowIndex,
anchorColumnIndex,
this.Rows.GetPreviousRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
true);
}
}
}
}
else if (this.Columns.DisplayInOrder(newEdgeColumnIndex, oldEdgeColumnIndex) &&
newEdgeRowIndex < oldEdgeRowIndex && anchorRowIndex >= oldEdgeRowIndex)
{
if (!this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex))
{
// h7
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(newEdgeColumnIndex, oldEdgeRowIndex, dataGridViewColumn.Index, anchorRowIndex, true);
SelectCellRange(newEdgeColumnIndex,
newEdgeRowIndex,
anchorColumnIndex,
this.Rows.GetPreviousRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
true);
}
else
{
if (this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex))
{
// a4
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[newEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
Debug.Assert(oldEdgeRowIndex <= anchorRowIndex);
SelectCellRange(dataGridViewColumn.Index, oldEdgeRowIndex, oldEdgeColumnIndex, anchorRowIndex, false);
SelectCellRange(anchorColumnIndex,
newEdgeRowIndex,
newEdgeColumnIndex,
this.Rows.GetPreviousRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
true);
}
else
{
// g8
SelectCellRange(anchorColumnIndex, oldEdgeRowIndex, oldEdgeColumnIndex, anchorRowIndex, false);
SelectCellRange(newEdgeColumnIndex, newEdgeRowIndex, anchorColumnIndex, anchorRowIndex, true);
}
}
}
else if (this.Columns.DisplayInOrder(newEdgeColumnIndex, oldEdgeColumnIndex) &&
!this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex) &&
newEdgeRowIndex > oldEdgeRowIndex && anchorRowIndex <= oldEdgeRowIndex)
{
// h8
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(newEdgeColumnIndex, anchorRowIndex, dataGridViewColumn.Index, oldEdgeRowIndex, true);
SelectCellRange(newEdgeColumnIndex,
this.Rows.GetNextRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
anchorColumnIndex,
newEdgeRowIndex,
true);
}
else if (this.Columns.DisplayInOrder(newEdgeColumnIndex, oldEdgeColumnIndex))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[newEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
if (newEdgeRowIndex == oldEdgeRowIndex)
{
if (this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex) || (anchorColumnIndex == newEdgeColumnIndex))
{
// a1
Debug.Assert(dataGridViewColumn != null);
if (oldEdgeRowIndex > anchorRowIndex)
{
SelectCellRange(dataGridViewColumn.Index, anchorRowIndex, oldEdgeColumnIndex, oldEdgeRowIndex, false);
}
else
{
SelectCellRange(dataGridViewColumn.Index, oldEdgeRowIndex, oldEdgeColumnIndex, anchorRowIndex, false);
}
}
}
else if (newEdgeRowIndex < oldEdgeRowIndex)
{
if (oldEdgeRowIndex > anchorRowIndex)
{
if (this.Columns.DisplayInOrder(newEdgeColumnIndex, oldEdgeColumnIndex))
{
if (anchorRowIndex <= newEdgeRowIndex)
{
if (this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex))
{
if (!this.Columns.DisplayInOrder(newEdgeColumnIndex, anchorColumnIndex))
{
// a2
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(dataGridViewColumn.Index, anchorRowIndex, oldEdgeColumnIndex, oldEdgeRowIndex, false);
SelectCellRange(anchorColumnIndex,
this.Rows.GetNextRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
newEdgeColumnIndex,
oldEdgeRowIndex,
false);
}
}
else
{
// d3
dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(oldEdgeColumnIndex,
this.Rows.GetNextRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
anchorColumnIndex,
oldEdgeRowIndex,
false);
SelectCellRange(newEdgeColumnIndex,
anchorRowIndex,
dataGridViewColumn.Index,
newEdgeRowIndex,
true);
}
}
}
}
}
else if (newEdgeRowIndex > oldEdgeRowIndex)
{
if (oldEdgeRowIndex < anchorRowIndex)
{
if ((this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex) || (anchorColumnIndex == newEdgeColumnIndex)) &&
newEdgeRowIndex <= anchorRowIndex)
{
// a3
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(dataGridViewColumn.Index, oldEdgeRowIndex, oldEdgeColumnIndex, anchorRowIndex, false);
SelectCellRange(anchorColumnIndex,
oldEdgeRowIndex,
newEdgeColumnIndex,
this.Rows.GetPreviousRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
false);
}
else
{
if (!this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex))
{
if (newEdgeRowIndex <= anchorRowIndex)
{
// c3
dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(oldEdgeColumnIndex,
oldEdgeRowIndex,
anchorColumnIndex,
this.Rows.GetPreviousRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
false);
SelectCellRange(newEdgeColumnIndex,
newEdgeRowIndex,
dataGridViewColumn.Index,
anchorRowIndex,
true);
}
}
}
}
else
{
if (this.Columns.DisplayInOrder(anchorColumnIndex, newEdgeColumnIndex) || (anchorColumnIndex == newEdgeColumnIndex))
{
// a5
Debug.Assert(oldEdgeRowIndex >= anchorRowIndex);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(dataGridViewColumn.Index, anchorRowIndex, oldEdgeColumnIndex, oldEdgeRowIndex, false);
SelectCellRange(anchorColumnIndex,
this.Rows.GetNextRow(anchorRowIndex, DataGridViewElementStates.Visible),
newEdgeColumnIndex,
newEdgeRowIndex,
true);
}
}
}
}
else if (this.Columns.DisplayInOrder(oldEdgeColumnIndex, newEdgeColumnIndex))
{
DataGridViewColumn dataGridViewColumn = this.Columns.GetPreviousColumn(this.Columns[newEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
if (newEdgeRowIndex == oldEdgeRowIndex)
{
if (this.Columns.DisplayInOrder(newEdgeColumnIndex, anchorColumnIndex) || (newEdgeColumnIndex == anchorColumnIndex))
{
// b1
Debug.Assert(dataGridViewColumn != null);
if (oldEdgeRowIndex > anchorRowIndex)
{
SelectCellRange(oldEdgeColumnIndex, anchorRowIndex, dataGridViewColumn.Index, oldEdgeRowIndex, false);
}
else
{
SelectCellRange(oldEdgeColumnIndex, oldEdgeRowIndex, dataGridViewColumn.Index, anchorRowIndex, false);
}
}
}
else if (newEdgeRowIndex < oldEdgeRowIndex)
{
if (oldEdgeRowIndex > anchorRowIndex)
{
if ((this.Columns.DisplayInOrder(newEdgeColumnIndex, anchorColumnIndex) || (newEdgeColumnIndex == anchorColumnIndex)) &&
newEdgeRowIndex >= anchorRowIndex)
{
// b2
SelectCellRange(oldEdgeColumnIndex, anchorRowIndex, dataGridViewColumn.Index, oldEdgeRowIndex, false);
SelectCellRange(newEdgeColumnIndex,
this.Rows.GetNextRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
anchorColumnIndex,
oldEdgeRowIndex,
false);
}
else
{
if (!this.Columns.DisplayInOrder(oldEdgeColumnIndex, anchorColumnIndex))
{
if (newEdgeRowIndex >= anchorRowIndex)
{
// d2
dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(anchorColumnIndex,
this.Rows.GetNextRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
oldEdgeColumnIndex,
oldEdgeRowIndex,
false);
SelectCellRange(dataGridViewColumn.Index,
anchorRowIndex,
newEdgeColumnIndex,
newEdgeRowIndex,
true);
}
}
}
}
}
else if (newEdgeRowIndex > oldEdgeRowIndex)
{
if (oldEdgeRowIndex < anchorRowIndex)
{
if ((this.Columns.DisplayInOrder(newEdgeColumnIndex, anchorColumnIndex) || (anchorColumnIndex == newEdgeColumnIndex)) &&
newEdgeRowIndex <= anchorRowIndex)
{
// b3
SelectCellRange(oldEdgeColumnIndex, oldEdgeRowIndex, dataGridViewColumn.Index, anchorRowIndex, false);
SelectCellRange(newEdgeColumnIndex,
oldEdgeRowIndex,
anchorColumnIndex,
this.Rows.GetPreviousRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
false);
}
else
{
if (!this.Columns.DisplayInOrder(oldEdgeColumnIndex, anchorColumnIndex))
{
if (newEdgeRowIndex <= anchorRowIndex)
{
// c2
dataGridViewColumn = this.Columns.GetNextColumn(this.Columns[oldEdgeColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.None);
Debug.Assert(dataGridViewColumn != null);
SelectCellRange(anchorColumnIndex,
oldEdgeRowIndex,
oldEdgeColumnIndex,
this.Rows.GetPreviousRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
false);
SelectCellRange(dataGridViewColumn.Index,
newEdgeRowIndex,
newEdgeColumnIndex,
anchorRowIndex,
true);
}
}
}
}
else
{
if (this.Columns.DisplayInOrder(newEdgeColumnIndex, anchorColumnIndex) || (anchorColumnIndex == newEdgeColumnIndex))
{
// b5
Debug.Assert(oldEdgeRowIndex >= anchorRowIndex);
SelectCellRange(oldEdgeColumnIndex, anchorRowIndex, dataGridViewColumn.Index, oldEdgeRowIndex, false);
SelectCellRange(newEdgeColumnIndex,
this.Rows.GetNextRow(oldEdgeRowIndex, DataGridViewElementStates.Visible),
anchorColumnIndex,
newEdgeRowIndex,
true);
}
}
}
}
else if (newEdgeRowIndex > oldEdgeRowIndex)
{
if (newEdgeColumnIndex == oldEdgeColumnIndex)
{
if (newEdgeRowIndex <= anchorRowIndex)
{
// c1
if (this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex))
{
SelectCellRange(anchorColumnIndex,
oldEdgeRowIndex,
oldEdgeColumnIndex,
this.Rows.GetPreviousRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
false);
}
else
{
SelectCellRange(oldEdgeColumnIndex,
oldEdgeRowIndex,
anchorColumnIndex,
this.Rows.GetPreviousRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
false);
}
}
}
}
else if (newEdgeRowIndex < oldEdgeRowIndex)
{
if (newEdgeColumnIndex == oldEdgeColumnIndex)
{
if (newEdgeRowIndex >= anchorRowIndex)
{
// d1
if (this.Columns.DisplayInOrder(anchorColumnIndex, oldEdgeColumnIndex))
{
SelectCellRange(anchorColumnIndex,
this.Rows.GetNextRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
oldEdgeColumnIndex,
oldEdgeRowIndex,
false);
}
else
{
SelectCellRange(oldEdgeColumnIndex,
this.Rows.GetNextRow(newEdgeRowIndex, DataGridViewElementStates.Visible),
anchorColumnIndex,
oldEdgeRowIndex,
false);
}
}
}
}
oldEdgeColumnIndex = newEdgeColumnIndex;
oldEdgeRowIndex = newEdgeRowIndex;
}
private void VertScrollTimer_Tick(object sender, System.EventArgs e)
{
BeginInvoke(new MethodInvoker(VertScrollTimerHandler));
}
private void VertScrollTimerHandler()
{
// Why would the vertical scroll timer be enabled when vertical selection is not occurring
Debug.Assert(this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] || this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect]);
Point ptMouse = PointToClient(Control.MousePosition);
HitTestInfo hti = HitTest(ptMouse.X, ptMouse.Y);
int xOffset, yOffset, mouseX = ptMouse.X, mouseY = ptMouse.Y;
if (GetOutOfBoundCorrectedHitTestInfo(ref hti, ref mouseX, ref mouseY, out xOffset, out yOffset))
{
if (yOffset != 0)
{
int absYOffset = Math.Abs(yOffset), normOffset = yOffset / absYOffset;
ScrollRowsByCount(normOffset, normOffset < 0 ? ScrollEventType.SmallDecrement : ScrollEventType.SmallIncrement);
this.vertScrollTimer.Interval = GetRowScrollRate(absYOffset);
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect])
{
hti = HitTest(mouseX, ptMouse.Y - yOffset - normOffset);
if (hti.row >= 0)
{
OnRowSelectMouseMove(hti);
}
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect])
{
if (xOffset != 0)
{
hti = HitTest(ptMouse.X - xOffset - (xOffset / Math.Abs(xOffset)), ptMouse.Y - yOffset - normOffset);
}
else
{
hti = HitTest(mouseX, ptMouse.Y - yOffset - normOffset);
}
if (hti.col >= 0 && hti.row >= 0)
{
OnCellSelectMouseMove(hti);
}
}
}
else
{
if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackRowSelect] && hti.row >= 0)
{
OnRowSelectMouseMove(hti);
}
else if (this.dataGridViewOper[DATAGRIDVIEWOPER_trackCellSelect] && hti.col >= 0 && hti.row >= 0)
{
OnCellSelectMouseMove(hti);
}
this.VertScrollTimer.Enabled = false;
}
}
}
private void WireEditingControlEvents()
{
Debug.Assert(this.editingPanel != null);
this.editingPanel.Click += new System.EventHandler(EditingControls_Click);
this.editingPanel.DoubleClick += new System.EventHandler(EditingControls_DoubleClick);
this.editingPanel.MouseClick += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseClick);
this.editingPanel.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDoubleClick);
this.editingPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDown);
this.editingPanel.MouseEnter += new System.EventHandler(EditingControls_MouseEnter);
this.editingPanel.MouseLeave += new System.EventHandler(EditingControls_MouseLeave);
this.editingPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseMove);
this.editingPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseUp);
Debug.Assert(this.editingControl != null);
this.editingControl.Click += new System.EventHandler(EditingControls_Click);
this.editingControl.DoubleClick += new System.EventHandler(EditingControls_DoubleClick);
this.editingControl.MouseClick += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseClick);
this.editingControl.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDoubleClick);
this.editingControl.MouseDown += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseDown);
this.editingControl.MouseEnter += new System.EventHandler(EditingControls_MouseEnter);
this.editingControl.MouseLeave += new System.EventHandler(EditingControls_MouseLeave);
this.editingControl.MouseMove += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseMove);
this.editingControl.MouseUp += new System.Windows.Forms.MouseEventHandler(EditingControls_MouseUp);
}
private void WireScrollBarsEvents()
{
if (this.horizScrollBar != null)
{
this.horizScrollBar.MouseEnter += new System.EventHandler(ScrollBar_MouseEnter);
this.horizScrollBar.MouseLeave += new System.EventHandler(ScrollBar_MouseLeave);
}
if (this.vertScrollBar != null)
{
this.vertScrollBar.MouseEnter += new System.EventHandler(ScrollBar_MouseEnter);
this.vertScrollBar.MouseLeave += new System.EventHandler(ScrollBar_MouseLeave);
}
}
/// <devdoc>
/// Handles the WM_CONTEXTMENU message
/// </devdoc>
/// <internalonly/>
internal override void WmContextMenu(ref Message m)
{
ContextMenuStrip contextMenuStrip;
int x = unchecked( (int)(short)(long)m.LParam);
int y = unchecked( (int) (long)m.LParam) >> 16;
Point client;
bool keyboardActivated = false;
// lparam will be exactly -1 when the user invokes the context menu
// with the keyboard.
//
if (unchecked( (int) (long)m.LParam) == -1)
{
keyboardActivated = true;
client = new Point(this.Width/2, this.Height/2);
contextMenuStrip = (ContextMenuStrip) this.ContextMenuStrip;
}
else
{
client = PointToClientInternal(new Point(x, y));
HitTestInfo hti = HitTest(client.X, client.Y);
DataGridViewCell dataGridViewCell = null;
switch (hti.Type)
{
case DataGridViewHitTestType.Cell:
dataGridViewCell = this.Rows.SharedRow(hti.row).Cells[hti.col];
break;
case DataGridViewHitTestType.ColumnHeader:
Debug.Assert(hti.row == -1);
dataGridViewCell = this.Columns[hti.col].HeaderCell;
break;
case DataGridViewHitTestType.RowHeader:
Debug.Assert(hti.col == -1);
dataGridViewCell = this.Rows.SharedRow(hti.row).HeaderCell;
break;
case DataGridViewHitTestType.TopLeftHeader:
Debug.Assert(hti.row == -1);
Debug.Assert(hti.col == -1);
dataGridViewCell = this.TopLeftHeaderCell;
break;
}
if (dataGridViewCell != null)
{
contextMenuStrip = dataGridViewCell.GetInheritedContextMenuStrip(hti.row);
}
else
{
contextMenuStrip = (ContextMenuStrip) this.ContextMenuStrip;
}
}
// VisualStudio7 # 156, only show the context menu when clicked in the client area
if (contextMenuStrip != null && this.ClientRectangle.Contains(client))
{
contextMenuStrip.ShowInternal(this, client, keyboardActivated);
}
else
{
DefWndProc(ref m);
}
}
/// <devdoc>
/// Handles the WM_GETDLGCODE message
/// </devdoc>
private void WmGetDlgCode(ref Message m)
{
m.Result = (IntPtr)((long)m.Result | NativeMethods.DLGC_WANTARROWS | NativeMethods.DLGC_WANTCHARS);
Keys modifierKeys = ModifierKeys;
if (GetTabKeyEffective((modifierKeys & Keys.Shift) == Keys.Shift, (modifierKeys & Keys.Control) == Keys.Control))
{
m.Result = (IntPtr) ((long) m.Result | NativeMethods.DLGC_WANTTAB);
}
}
private unsafe bool WmNotify(ref Message m)
{
if (m.LParam == IntPtr.Zero)
{
return false;
}
NativeMethods.NMHDR* nmhdr = (NativeMethods.NMHDR *)m.LParam;
if (nmhdr->code == NativeMethods.TTN_GETDISPINFO && !DesignMode)
{
string toolTip = this.ToolTipPrivate;
if (!String.IsNullOrEmpty(toolTip))
{
// MSDN: Setting the max width has the added benefit of enabling multiline tool tips!
UnsafeNativeMethods.SendMessage(new HandleRef(this, nmhdr->hwndFrom), NativeMethods.TTM_SETMAXTIPWIDTH, 0, SystemInformation.MaxWindowTrackSize.Width);
NativeMethods.TOOLTIPTEXT ttt = (NativeMethods.TOOLTIPTEXT) m.GetLParam(typeof(NativeMethods.TOOLTIPTEXT));
ttt.lpszText = toolTip;
if (this.RightToLeft == RightToLeft.Yes)
{
ttt.uFlags |= NativeMethods.TTF_RTLREADING;
}
Marshal.StructureToPtr(ttt, m.LParam, false);
return true;
}
}
return false;
}
/// <include file='doc\DataGridView.uex' path='docs/doc[@for="DataGridView.WndProc"]/*' />
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case NativeMethods.WM_GETDLGCODE:
WmGetDlgCode(ref m);
return;
case NativeMethods.WM_LBUTTONDBLCLK:
case NativeMethods.WM_LBUTTONDOWN:
// If the OnEnter procedure is called, it's because of a mouse down event, and not a TAB key.
this.dataGridViewOper[DATAGRIDVIEWOPER_inMouseDown] = true;
try
{
base.WndProc(ref m);
}
finally
{
this.dataGridViewOper[DATAGRIDVIEWOPER_inMouseDown] = false;
}
return;
case NativeMethods.WM_NOTIFY:
if (WmNotify(ref m))
{
// we are done - skip default handling
return;
}
break;
case NativeMethods.WM_IME_STARTCOMPOSITION:
case NativeMethods.WM_IME_COMPOSITION:
if (this.editingControl != null)
{
// Make sure that the first character is forwarded to the editing control.
this.editingControl.SendMessage(m.Msg, m.WParam, m.LParam);
}
break;
}
base.WndProc(ref m);
}
}
}
|