DataGridViewCell.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / DataGridViewCell.cs / 1 / DataGridViewCell.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

// Code taken from ASP.NET file xsp\System\Web\httpserverutility.cs 
// Don't entity encode high chars (160 to 256), to fix bugs VSWhidbey 85857/111927 
// ASP.NET team decided to postpone those bugs and leave behavior as is in Whidbey.
#define ENTITY_ENCODE_HIGH_ASCII_CHARS 

namespace System.Windows.Forms
{
    using System; 
    using System.IO;
    using System.Text; 
    using System.Diagnostics; 
    using System.Drawing;
    using System.Reflection; 
    using System.Globalization;
    using System.ComponentModel;
    using System.Windows.Forms.Internal;
    using System.Security.Permissions; 
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices; 
 
    /// 
    ///  
    ///    Identifies a cell in the dataGridView.
    /// 
    [
        TypeConverterAttribute(typeof(DataGridViewCellConverter)) 
    ]
    public abstract class DataGridViewCell : DataGridViewElement, ICloneable, IDisposable 
    { 
        private const TextFormatFlags textFormatSupportedFlags = TextFormatFlags.SingleLine | /*TextFormatFlags.NoFullWidthCharacterBreak |*/ TextFormatFlags.WordBreak | TextFormatFlags.NoPrefix;
        private const int DATAGRIDVIEWCELL_constrastThreshold = 1000; 
        private const int DATAGRIDVIEWCELL_highConstrastThreshold = 2000;
        private const int DATAGRIDVIEWCELL_maxToolTipLength = 288;
        private const int DATAGRIDVIEWCELL_maxToolTipCutOff = 256;
        private const int DATAGRIDVIEWCELL_toolTipEllipsisLength = 3; 
        private const string DATAGRIDVIEWCELL_toolTipEllipsis = "...";
        private const byte DATAGRIDVIEWCELL_flagAreaNotSet = 0x00; 
        private const byte DATAGRIDVIEWCELL_flagDataArea = 0x01; 
        private const byte DATAGRIDVIEWCELL_flagErrorArea = 0x02;
        internal const byte DATAGRIDVIEWCELL_iconMarginWidth = 4;      // 4 pixels of margin on the left and right of icons 
        internal const byte DATAGRIDVIEWCELL_iconMarginHeight = 4;     // 4 pixels of margin on the top and bottom of icons
        internal const byte DATAGRIDVIEWCELL_iconsWidth = 12;          // all icons are 12 pixels wide - make sure that it stays that way
        internal const byte DATAGRIDVIEWCELL_iconsHeight = 11;         // all icons are 11 pixels tall - make sure that it stays that way
 
        internal static readonly int PropCellValue = PropertyStore.CreateKey();
        private static readonly int PropCellContextMenuStrip = PropertyStore.CreateKey(); 
        private static readonly int PropCellErrorText = PropertyStore.CreateKey(); 
        private static readonly int PropCellStyle = PropertyStore.CreateKey();
        private static readonly int PropCellValueType = PropertyStore.CreateKey(); 
        private static readonly int PropCellTag = PropertyStore.CreateKey();
        private static readonly int PropCellToolTipText = PropertyStore.CreateKey();
        private static readonly int PropCellAccessibilityObject = PropertyStore.CreateKey();
 
        private static Bitmap errorBmp = null;
 
        private PropertyStore propertyStore;          // Contains all properties that are not always set. 
        private DataGridViewRow owningRow;
        private DataGridViewColumn owningColumn; 

        private static Type stringType = typeof(string);        // cache the string type for performance

        private byte flags;  // see DATAGRIDVIEWCELL_flag* consts above 

        ///  
        ///  
        ///    
        ///       Initializes a new instance of the  class. 
        ///    
        /// 
        protected DataGridViewCell() : base()
        { 
            this.propertyStore = new PropertyStore();
            this.StateInternal = DataGridViewElementStates.None; 
        } 

        ///  
        ~DataGridViewCell()
        {
            Dispose(false);
        } 

        ///  
        [ 
            Browsable(false)
        ] 
        public AccessibleObject AccessibilityObject
        {
            get
            { 
                AccessibleObject result = (AccessibleObject) this.Properties.GetObject(PropCellAccessibilityObject);
                if (result == null) 
                { 
                    result = this.CreateAccessibilityInstance();
                    this.Properties.SetObject(PropCellAccessibilityObject, result); 
                }

                return result;
            } 
        }
 
        ///  
        /// 
        /// Gets or sets the Index of a column in the  control. 
        /// 
        public int ColumnIndex
        {
            get 
            {
                if (this.owningColumn == null) 
                { 
                    return -1;
                } 
                return this.owningColumn.Index;
            }
        }
 
        /// 
        [ 
            Browsable(false) 
        ]
        public Rectangle ContentBounds 
        {
            get
            {
                return GetContentBounds(this.RowIndex); 
            }
        } 
 
        /// 
        [ 
            DefaultValue(null)
        ]
        public virtual ContextMenuStrip ContextMenuStrip
        { 
            get
            { 
                return GetContextMenuStrip(this.RowIndex); 
            }
            set 
            {
                this.ContextMenuStripInternal = value;
            }
        } 

        private ContextMenuStrip ContextMenuStripInternal 
        { 
            get
            { 
                return (ContextMenuStrip)this.Properties.GetObject(PropCellContextMenuStrip);
            }
            set
            { 
                ContextMenuStrip oldValue = (ContextMenuStrip)this.Properties.GetObject(PropCellContextMenuStrip);
                if (oldValue != value) 
                { 
                    EventHandler disposedHandler = new EventHandler(DetachContextMenuStrip);
                    if (oldValue != null) 
                    {
                        oldValue.Disposed -= disposedHandler;
                    }
                    this.Properties.SetObject(PropCellContextMenuStrip, value); 
                    if (value != null)
                    { 
                        value.Disposed += disposedHandler; 
                    }
                    if (this.DataGridView != null) 
                    {
                        this.DataGridView.OnCellContextMenuStripChanged(this);
                    }
                } 
            }
        } 
 
        private byte CurrentMouseLocation
        { 
            get
            {
                return (byte) (this.flags & (DATAGRIDVIEWCELL_flagDataArea | DATAGRIDVIEWCELL_flagErrorArea));
            } 
            set
            { 
                this.flags = (byte)(this.flags & ~(DATAGRIDVIEWCELL_flagDataArea | DATAGRIDVIEWCELL_flagErrorArea)); 
                this.flags |= value;
            } 
        }

        /// 
        [ 
            Browsable(false)
        ] 
        public virtual object DefaultNewRowValue 
        {
            get 
            {
                return null;
            }
        } 

        ///  
        [ 
            Browsable(false)
        ] 
        public virtual bool Displayed
        {
            get
            { 
                Debug.Assert((this.State & DataGridViewElementStates.Displayed) == 0);
 
                if (this.DataGridView == null) 
                {
                    // No detached element is displayed. 
                    return false;
                }

                if (this.DataGridView != null && this.RowIndex >= 0 && this.ColumnIndex >= 0) 
                {
                    Debug.Assert(this.DataGridView.Rows.GetRowState(this.RowIndex) == this.DataGridView.Rows.SharedRow(this.RowIndex).State); 
                    return this.owningColumn.Displayed && this.owningRow.Displayed; 
                }
 
                return false;
            }
        }
 
        /// 
        [ 
            Browsable(false), 
            EditorBrowsable(EditorBrowsableState.Advanced)
        ] 
        public object EditedFormattedValue
        {
            get
            { 
                if (this.DataGridView == null)
                { 
                    return null; 
                }
                Debug.Assert(this.RowIndex >= -1); 
                DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, this.RowIndex, false);
                return GetEditedFormattedValue(GetValue(this.RowIndex), this.RowIndex, ref dataGridViewCellStyle, DataGridViewDataErrorContexts.Formatting);
            }
        } 

        ///  
        [ 
            Browsable(false),
            EditorBrowsable(EditorBrowsableState.Advanced) 
        ]
        public virtual Type EditType
        {
            get 
            {
                return typeof(System.Windows.Forms.DataGridViewTextBoxEditingControl); 
            } 
        }
 
        private static Bitmap ErrorBitmap
        {
            get
            { 
                if (errorBmp == null)
                { 
                    errorBmp = GetBitmap("DataGridViewRow.error.bmp"); 
                }
                return errorBmp; 
            }
        }

        ///  
        [
            Browsable(false), 
            EditorBrowsable(EditorBrowsableState.Advanced), 
            SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods") // ErrorIconBounds/GetErrorIconBounds existence is intentional
        ] 
        public Rectangle ErrorIconBounds
        {
            get
            { 
                return GetErrorIconBounds(this.RowIndex);
            } 
        } 

        ///  
        [
            Browsable(false)
        ]
        public string ErrorText 
        {
            get 
            { 
                return GetErrorText(this.RowIndex);
            } 
            set
            {
                this.ErrorTextInternal = value;
            } 
        }
 
        private string ErrorTextInternal 
        {
            get 
            {
                object errorText = this.Properties.GetObject(PropCellErrorText);
                return (errorText == null) ? string.Empty : (string)errorText;
            } 
            set
            { 
                string errorText = this.ErrorTextInternal; 
                if (!string.IsNullOrEmpty(value) || this.Properties.ContainsObject(PropCellErrorText))
                { 
                    this.Properties.SetObject(PropCellErrorText, value);
                }
                if (this.DataGridView != null && !errorText.Equals(this.ErrorTextInternal))
                { 
                    this.DataGridView.OnCellErrorTextChanged(this);
                } 
            } 
        }
 
        /// 
        [
            Browsable(false)
        ] 
        public object FormattedValue
        { 
            get 
            {
                if (this.DataGridView == null) 
                {
                    return null;
                }
                Debug.Assert(this.RowIndex >= -1); 
                DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, this.RowIndex, false);
                return GetFormattedValue(this.RowIndex, ref dataGridViewCellStyle, DataGridViewDataErrorContexts.Formatting); 
            } 
        }
 
        /// 
        [
            Browsable(false)
        ] 
        public virtual Type FormattedValueType
        { 
            get 
            {
                return this.ValueType; 
            }
        }

        private TypeConverter FormattedValueTypeConverter 
        {
            get 
            { 
                TypeConverter formattedValueTypeConverter = null;
                if (this.FormattedValueType != null) 
                {
                    if (this.DataGridView != null)
                    {
                        formattedValueTypeConverter = this.DataGridView.GetCachedTypeConverter(this.FormattedValueType); 
                    }
                    else 
                    { 
                        formattedValueTypeConverter = TypeDescriptor.GetConverter(this.FormattedValueType);
                    } 
                }
                return formattedValueTypeConverter;
            }
        } 

        ///  
        [ 
            Browsable(false)
        ] 
        public virtual bool Frozen
        {
            get
            { 
                Debug.Assert((this.State & DataGridViewElementStates.Frozen) == 0);
 
                if (this.DataGridView != null && this.RowIndex >= 0 && this.ColumnIndex >= 0) 
                {
                    Debug.Assert(this.DataGridView.Rows.GetRowState(this.RowIndex) == this.DataGridView.Rows.SharedRow(this.RowIndex).State); 
                    return this.owningColumn.Frozen && this.owningRow.Frozen;
                }
                else if (this.owningRow != null && (this.owningRow.DataGridView == null || this.RowIndex >= 0))
                { 
                    return this.owningRow.Frozen;
                } 
                return false; 
            }
        } 

        internal bool HasErrorText
        {
            get 
            {
                return this.Properties.ContainsObject(PropCellErrorText) && this.Properties.GetObject(PropCellErrorText) != null; 
            } 
        }
 
        /// 
        [
            Browsable(false)
        ] 
        public bool HasStyle
        { 
            get 
            {
                return this.Properties.ContainsObject(PropCellStyle) && this.Properties.GetObject(PropCellStyle) != null; 
            }
        }

        internal bool HasToolTipText 
        {
            get 
            { 
                return this.Properties.ContainsObject(PropCellToolTipText) && this.Properties.GetObject(PropCellToolTipText) != null;
            } 
        }

        internal bool HasValue
        { 
            get
            { 
                return this.Properties.ContainsObject(PropCellValue) && this.Properties.GetObject(PropCellValue) != null; 
            }
        } 

        internal virtual bool HasValueType
        {
            get 
            {
                return this.Properties.ContainsObject(PropCellValueType) && this.Properties.GetObject(PropCellValueType) != null; 
            } 
        }
 
        /// 
        [
            Browsable(false),
            SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods") // InheritedState/GetInheritedState existence is intentional 
        ]
        public DataGridViewElementStates InheritedState 
        { 
            get
            { 
                return GetInheritedState(this.RowIndex);
            }
        }
 
        /// 
        [ 
            Browsable(false), 
            SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods") // InheritedStyle/GetInheritedStyle existence is intentional
        ] 
        public DataGridViewCellStyle InheritedStyle
        {
            get
            { 
                // this.RowIndex could be -1 if:
                // - the developer makes a mistake & calls dataGridView1.Rows.SharedRow(y).Cells(x).InheritedStyle. 
                // - the InheritedStyle of a ColumnHeaderCell is accessed. 
                return GetInheritedStyleInternal(this.RowIndex);
            } 
        }

        /// 
        [ 
            Browsable(false)
        ] 
        public bool IsInEditMode 
        {
            get 
            {
                if (this.DataGridView == null)
                {
                    return false; 
                }
                if (this.RowIndex == -1) 
                { 
                    throw new InvalidOperationException(SR.GetString(SR.DataGridView_InvalidOperationOnSharedCell));
                } 
                Point ptCurrentCell = this.DataGridView.CurrentCellAddress;
                return ptCurrentCell.X != -1 &&
                       ptCurrentCell.X == this.ColumnIndex &&
                       ptCurrentCell.Y == this.RowIndex && 
                       this.DataGridView.IsCurrentCellInEditMode;
            } 
        } 

        ///  
        [
            Browsable(false),
            EditorBrowsable(EditorBrowsableState.Advanced)
        ] 
        public DataGridViewColumn OwningColumn
        { 
            get 
            {
                return this.owningColumn; 
            }
        }

        internal DataGridViewColumn OwningColumnInternal 
        {
            set 
            { 
                this.owningColumn = value;
            } 
        }

        /// 
        [ 
            Browsable(false),
            EditorBrowsable(EditorBrowsableState.Advanced) 
        ] 
        public DataGridViewRow OwningRow
        { 
            get
            {
                return this.owningRow;
            } 
        }
 
        internal DataGridViewRow OwningRowInternal 
        {
            set 
            {
                this.owningRow = value;
            }
        } 

        ///  
        [ 
            Browsable(false)
        ] 
        public Size PreferredSize
        {
            get
            { 
                return GetPreferredSize(this.RowIndex);
            } 
        } 

        internal PropertyStore Properties 
        {
            get
            {
                return this.propertyStore; 
            }
        } 
 
        /// 
        [ 
            Browsable(false),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public virtual bool ReadOnly 
        {
            get 
            { 
                if ((this.State & DataGridViewElementStates.ReadOnly) != 0)
                { 
                    return true;
                }
                if (this.owningRow != null && (this.owningRow.DataGridView == null || this.RowIndex >= 0) && this.owningRow.ReadOnly)
                { 
                    return true;
                } 
                if (this.DataGridView != null && this.RowIndex >= 0 && this.ColumnIndex >= 0) 
                {
                    Debug.Assert(this.DataGridView.Rows.GetRowState(this.RowIndex) == this.DataGridView.Rows.SharedRow(this.RowIndex).State); 
                    return this.owningColumn.ReadOnly;
                }
                return false;
            } 
            set
            { 
                if (this.DataGridView != null) 
                {
                    if (this.RowIndex == -1) 
                    {
                        throw new InvalidOperationException(SR.GetString(SR.DataGridView_InvalidOperationOnSharedCell));
                    }
                    Debug.Assert(this.ColumnIndex >= 0); 
                    // When the whole grid is read-only, we ignore the request.
                    if (value != this.ReadOnly && !this.DataGridView.ReadOnly) 
                    { 
                        this.DataGridView.OnDataGridViewElementStateChanging(this, -1, DataGridViewElementStates.ReadOnly);
                        this.DataGridView.SetReadOnlyCellCore(this.ColumnIndex, this.RowIndex, value); // this may trigger a call to set_ReadOnlyInternal 
                    }
                }
                else
                { 
                    if (this.owningRow == null)
                    { 
                        if (value != this.ReadOnly) 
                        {
                            // We do not allow the read-only flag of a cell to be changed before it is added to a row. 
                            throw new InvalidOperationException(SR.GetString(SR.DataGridViewCell_CannotSetReadOnlyState));
                        }
                    }
                    else 
                    {
                        this.owningRow.SetReadOnlyCellCore(this, value); 
                    } 
                }
            } 
        }

        internal bool ReadOnlyInternal
        { 
            set
            { 
                Debug.Assert(value != this.ReadOnly); 
                if (value)
                { 
                    this.StateInternal = this.State | DataGridViewElementStates.ReadOnly;
                }
                else
                { 
                    this.StateInternal = this.State & ~DataGridViewElementStates.ReadOnly;
                } 
                if (this.DataGridView != null) 
                {
                    this.DataGridView.OnDataGridViewElementStateChanged(this, -1, DataGridViewElementStates.ReadOnly); 
                }
            }
        }
 
        /// 
        [ 
            Browsable(false) 
        ]
        public virtual bool Resizable 
        {
            get
            {
                Debug.Assert((this.State & DataGridViewElementStates.Resizable) == 0); 

                if (this.owningRow != null && (this.owningRow.DataGridView == null || this.RowIndex >= 0) && this.owningRow.Resizable == DataGridViewTriState.True) 
                { 
                    return true;
                } 

                if (this.DataGridView != null && this.RowIndex >= 0 && this.ColumnIndex >= 0)
                {
                    Debug.Assert(this.DataGridView.Rows.GetRowState(this.RowIndex) == this.DataGridView.Rows.SharedRow(this.RowIndex).State); 
                    return this.owningColumn.Resizable == DataGridViewTriState.True;
                } 
 
                return false;
            } 
        }

        /// 
        ///  
        /// Gets or sets the index of a row in the  control.
        ///  
        [ 
            Browsable(false)
        ] 
        public int RowIndex
        {
            get
            { 
                if (this.owningRow == null)
                { 
                    return -1; 
                }
                return this.owningRow.Index; 
            }
        }

        ///  
        [
            Browsable(false), 
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public virtual bool Selected 
        {
            get
            {
                if ((this.State & DataGridViewElementStates.Selected) != 0) 
                {
                    return true; 
                } 

                if (this.owningRow != null && (this.owningRow.DataGridView == null || this.RowIndex >= 0) && this.owningRow.Selected) 
                {
                    return true;
                }
 
                if (this.DataGridView != null && this.RowIndex >= 0 && this.ColumnIndex >= 0)
                { 
                    Debug.Assert(this.DataGridView.Rows.GetRowState(this.RowIndex) == this.DataGridView.Rows.SharedRow(this.RowIndex).State); 
                    return this.owningColumn.Selected;
                } 

                return false;
            }
            set 
            {
                if (this.DataGridView != null) 
                { 
                    if (this.RowIndex == -1)
                    { 
                        throw new InvalidOperationException(SR.GetString(SR.DataGridView_InvalidOperationOnSharedCell));
                    }
                    Debug.Assert(this.ColumnIndex >= 0);
                    this.DataGridView.SetSelectedCellCoreInternal(this.ColumnIndex, this.RowIndex, value); // this may trigger a call to set_SelectedInternal 
                }
                else if (value) 
                { 
                    // We do not allow the selection of a cell to be set before the row gets added to the dataGridView.
                    throw new InvalidOperationException(SR.GetString(SR.DataGridViewCell_CannotSetSelectedState)); 
                }
            }
        }
 
        internal bool SelectedInternal
        { 
            set 
            {
                Debug.Assert(value != this.Selected); 
                if (value)
                {
                    this.StateInternal = this.State | DataGridViewElementStates.Selected;
                } 
                else
                { 
                    this.StateInternal = this.State & ~DataGridViewElementStates.Selected; 
                }
                if (this.DataGridView != null) 
                {
                    this.DataGridView.OnDataGridViewElementStateChanged(this, -1, DataGridViewElementStates.Selected);
                }
            } 
        }
 
        ///  
        [
            Browsable(false), 
            SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods") // Size/GetSize existence is intentional
        ]
        public Size Size
        { 
            get
            { 
                return GetSize(this.RowIndex); 
            }
        } 

        internal Rectangle StdBorderWidths
        {
            get 
            {
                if (this.DataGridView != null) 
                { 
                    DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder = new DataGridViewAdvancedBorderStyle(), dgvabsEffective;
                    dgvabsEffective = AdjustCellBorderStyle(this.DataGridView.AdvancedCellBorderStyle, 
                        dataGridViewAdvancedBorderStylePlaceholder,
                        false /*singleVerticalBorderAdded*/,
                        false /*singleHorizontalBorderAdded*/,
                        false /*isFirstDisplayedColumn*/, 
                        false /*isFirstDisplayedRow*/);
                    return BorderWidths(dgvabsEffective); 
                } 
                else
                { 
                    return Rectangle.Empty;
                }
            }
        } 

        ///  
        [ 
            Browsable(true)
        ] 
        public DataGridViewCellStyle Style
        {
            get
            { 
                DataGridViewCellStyle dgvcs = (DataGridViewCellStyle)this.Properties.GetObject(PropCellStyle);
                if (dgvcs == null) 
                { 
                    dgvcs = new DataGridViewCellStyle();
                    dgvcs.AddScope(this.DataGridView, DataGridViewCellStyleScopes.Cell); 
                    this.Properties.SetObject(PropCellStyle, dgvcs);
                }
                return dgvcs;
            } 
            set
            { 
                DataGridViewCellStyle dgvcs = null; 
                if (this.HasStyle)
                { 
                    dgvcs = this.Style;
                    dgvcs.RemoveScope(DataGridViewCellStyleScopes.Cell);
                }
                if (value != null || this.Properties.ContainsObject(PropCellStyle)) 
                {
                    if (value != null) 
                    { 
                        value.AddScope(this.DataGridView, DataGridViewCellStyleScopes.Cell);
                    } 
                    this.Properties.SetObject(PropCellStyle, value);
                }
                if (((dgvcs != null && value == null) ||
                    (dgvcs == null && value != null) || 
                    (dgvcs != null && value != null && !dgvcs.Equals(this.Style))) && this.DataGridView != null)
                { 
                    this.DataGridView.OnCellStyleChanged(this); 
                }
            } 
        }

        /// 
        [ 
            SRCategory(SR.CatData),
            Localizable(false), 
            Bindable(true), 
            SRDescription(SR.ControlTagDescr),
            DefaultValue(null), 
            TypeConverter(typeof(StringConverter))
        ]
        public object Tag
        { 
            get
            { 
                return this.Properties.GetObject(PropCellTag); 
            }
            set 
            {
                if (value != null || this.Properties.ContainsObject(PropCellTag))
                {
                    this.Properties.SetObject(PropCellTag, value); 
                }
            } 
        } 

        ///  
        [
            Browsable(false),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public string ToolTipText
        { 
            get 
            {
                return GetToolTipText(this.RowIndex); 
            }
            set
            {
                this.ToolTipTextInternal = value; 
            }
        } 
 
        private string ToolTipTextInternal
        { 
            get
            {
                object toolTipText = this.Properties.GetObject(PropCellToolTipText);
                return (toolTipText == null) ? string.Empty : (string)toolTipText; 
            }
            set 
            { 
                string toolTipText = this.ToolTipTextInternal;
                if (!String.IsNullOrEmpty(value) || this.Properties.ContainsObject(PropCellToolTipText)) 
                {
                    this.Properties.SetObject(PropCellToolTipText, value);
                }
                if (this.DataGridView != null && !toolTipText.Equals(this.ToolTipTextInternal)) 
                {
                    this.DataGridView.OnCellToolTipTextChanged(this); 
                } 
            }
        } 

        /// 
        [
            Browsable(false) 
        ]
        public object Value 
        { 
            get
            { 
                Debug.Assert(this.RowIndex >= -1);
                return GetValue(this.RowIndex);
            }
            set 
            {
                Debug.Assert(this.RowIndex >= -1); 
                SetValue(this.RowIndex, value); 
            }
        } 

        /// 
        [
            Browsable(false) 
        ]
        public virtual Type ValueType 
        { 
            get
            { 
                Type cellValueType = (Type) this.Properties.GetObject(PropCellValueType);
                if (cellValueType == null && this.OwningColumn != null)
                {
                    cellValueType = this.OwningColumn.ValueType; 
                }
 
                return cellValueType; 
            }
            set 
            {
                if (value != null || this.Properties.ContainsObject(PropCellValueType))
                {
                    this.Properties.SetObject(PropCellValueType, value); 
                }
            } 
        } 

        private TypeConverter ValueTypeConverter 
        {
            get
            {
                TypeConverter valueTypeConverter = null; 
                if (this.OwningColumn != null)
                { 
                    valueTypeConverter = this.OwningColumn.BoundColumnConverter; 
                }
                if (valueTypeConverter == null && this.ValueType != null) 
                {
                    if (this.DataGridView != null)
                    {
                        valueTypeConverter = this.DataGridView.GetCachedTypeConverter(this.ValueType); 
                    }
                    else 
                    { 
                        valueTypeConverter = TypeDescriptor.GetConverter(this.ValueType);
                    } 
                }
                return valueTypeConverter;
            }
        } 

        ///  
        [ 
            Browsable(false)
        ] 
        public virtual bool Visible
        {
            get
            { 
                Debug.Assert((this.State & DataGridViewElementStates.Visible) == 0);
 
                if (this.DataGridView != null && this.RowIndex >= 0 && this.ColumnIndex >= 0) 
                {
                    Debug.Assert(this.DataGridView.Rows.GetRowState(this.RowIndex) == this.DataGridView.Rows.SharedRow(this.RowIndex).State); 
                    return this.owningColumn.Visible && this.owningRow.Visible;
                }
                else if (this.owningRow != null && (this.owningRow.DataGridView == null || this.RowIndex >= 0))
                { 
                    return this.owningRow.Visible;
                } 
                return false; 
            }
        } 


        /// 
        [ 
            EditorBrowsable(EditorBrowsableState.Advanced)
        ] 
        public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle(DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput, 
            DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder,
            bool singleVerticalBorderAdded, 
            bool singleHorizontalBorderAdded,
            bool isFirstDisplayedColumn,
            bool isFirstDisplayedRow)
        { 
            switch (dataGridViewAdvancedBorderStyleInput.All)
            { 
                case DataGridViewAdvancedCellBorderStyle.OutsetPartial: 
                    Debug.Fail("DataGridViewRow.AdjustCellBorderStyle - Unexpected DataGridViewAdvancedCellBorderStyle.OutsetPartial");
                    break; 

                case DataGridViewAdvancedCellBorderStyle.Single:
                    if (this.DataGridView != null && this.DataGridView.RightToLeftInternal)
                    { 
                        dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.Single;
                        dataGridViewAdvancedBorderStylePlaceholder.RightInternal = (isFirstDisplayedColumn && singleVerticalBorderAdded) ? DataGridViewAdvancedCellBorderStyle.Single : DataGridViewAdvancedCellBorderStyle.None; 
                    } 
                    else
                    { 
                        dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = (isFirstDisplayedColumn && singleVerticalBorderAdded) ? DataGridViewAdvancedCellBorderStyle.Single : DataGridViewAdvancedCellBorderStyle.None;
                        dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.Single;
                    }
                    dataGridViewAdvancedBorderStylePlaceholder.TopInternal = (isFirstDisplayedRow && singleHorizontalBorderAdded) ? DataGridViewAdvancedCellBorderStyle.Single : DataGridViewAdvancedCellBorderStyle.None; 
                    dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Single;
                    return dataGridViewAdvancedBorderStylePlaceholder; 
 
                case DataGridViewAdvancedCellBorderStyle.NotSet:
                    if (this.DataGridView != null && this.DataGridView.AdvancedCellBorderStyle == dataGridViewAdvancedBorderStyleInput) 
                    {
                        switch (this.DataGridView.CellBorderStyle)
                        {
                            case DataGridViewCellBorderStyle.SingleVertical: 
                                if (this.DataGridView.RightToLeftInternal)
                                { 
                                    dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.Single; 
                                    dataGridViewAdvancedBorderStylePlaceholder.RightInternal = (isFirstDisplayedColumn && singleVerticalBorderAdded) ? DataGridViewAdvancedCellBorderStyle.Single : DataGridViewAdvancedCellBorderStyle.None;
                                } 
                                else
                                {
                                    dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = (isFirstDisplayedColumn && singleVerticalBorderAdded) ? DataGridViewAdvancedCellBorderStyle.Single : DataGridViewAdvancedCellBorderStyle.None;
                                    dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.Single; 
                                }
                                dataGridViewAdvancedBorderStylePlaceholder.TopInternal = DataGridViewAdvancedCellBorderStyle.None; 
                                dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.None; 
                                return dataGridViewAdvancedBorderStylePlaceholder;
 
                            case DataGridViewCellBorderStyle.SingleHorizontal:
                                dataGridViewAdvancedBorderStylePlaceholder.LeftInternal = DataGridViewAdvancedCellBorderStyle.None;
                                dataGridViewAdvancedBorderStylePlaceholder.RightInternal = DataGridViewAdvancedCellBorderStyle.None;
                                dataGridViewAdvancedBorderStylePlaceholder.TopInternal = (isFirstDisplayedRow && singleHorizontalBorderAdded) ? DataGridViewAdvancedCellBorderStyle.Single : DataGridViewAdvancedCellBorderStyle.None; 
                                dataGridViewAdvancedBorderStylePlaceholder.BottomInternal = DataGridViewAdvancedCellBorderStyle.Single;
                                return dataGridViewAdvancedBorderStylePlaceholder; 
                        } 
                    }
                    break; 
            }
            return dataGridViewAdvancedBorderStyleInput;
        }
 
        /// 
        protected virtual Rectangle BorderWidths(DataGridViewAdvancedBorderStyle advancedBorderStyle) 
        { 
            Rectangle rect = new Rectangle();
 
            rect.X = (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.None) ? 0 : 1;
            if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble)
            {
                rect.X++; 
            }
 
            rect.Y = (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) ? 0 : 1; 
            if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.InsetDouble)
            { 
                rect.Y++;
            }

            rect.Width = (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.None) ? 0 : 1; 
            if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble)
            { 
                rect.Width++; 
            }
 
            rect.Height = (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.None) ? 0 : 1;
            if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.InsetDouble)
            {
                rect.Height++; 
            }
 
            if (this.owningColumn != null) 
            {
                if (this.DataGridView != null && this.DataGridView.RightToLeftInternal) 
                {
                    rect.X += this.owningColumn.DividerWidth;
                }
                else 
                {
                    rect.Width += this.owningColumn.DividerWidth; 
                } 
            }
            if (this.owningRow != null) 
            {
                rect.Height += this.owningRow.DividerHeight;
            }
 
            return rect;
        } 
 
        // Called when the row that owns the editing control gets unshared.
        // Too late in the product cycle to make this a public method. 
        internal virtual void CacheEditingControl()
        {
        }
 
        /* Unused at this point.
        internal DataGridViewElementStates CellStateFromColumnRowStates() 
        { 
            Debug.Assert(this.DataGridView != null);
            Debug.Assert(this.RowIndex >= 0); 
            return CellStateFromColumnRowStates(this.owningRow.State);
        }*/

        internal DataGridViewElementStates CellStateFromColumnRowStates(DataGridViewElementStates rowState) 
        {
            Debug.Assert(this.DataGridView != null); 
            Debug.Assert(this.ColumnIndex >= 0); 
            DataGridViewElementStates orFlags = DataGridViewElementStates.ReadOnly | DataGridViewElementStates.Resizable | DataGridViewElementStates.Selected;
            DataGridViewElementStates andFlags = DataGridViewElementStates.Displayed | DataGridViewElementStates.Frozen | DataGridViewElementStates.Visible; 
            DataGridViewElementStates cellState = (this.owningColumn.State & orFlags);
            cellState |= (rowState & orFlags);
            cellState |= ((this.owningColumn.State & andFlags) & (rowState & andFlags));
            return cellState; 
        }
 
        ///  
        [
            SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. 
        ]
        protected virtual bool ClickUnsharesRow(DataGridViewCellEventArgs e)
        {
            return false; 
        }
 
        internal bool ClickUnsharesRowInternal(DataGridViewCellEventArgs e) 
        {
            return ClickUnsharesRow(e); 
        }

        internal void CloneInternal(DataGridViewCell dataGridViewCell)
        { 
            if (this.HasValueType)
            { 
                dataGridViewCell.ValueType = this.ValueType; 
            }
            if (this.HasStyle) 
            {
                dataGridViewCell.Style = new DataGridViewCellStyle(this.Style);
            }
            if (this.HasErrorText) 
            {
                dataGridViewCell.ErrorText = this.ErrorTextInternal; 
            } 
            if (this.HasToolTipText)
            { 
                dataGridViewCell.ToolTipText = this.ToolTipTextInternal;
            }
            if (this.ContextMenuStripInternal != null)
            { 
                dataGridViewCell.ContextMenuStrip = this.ContextMenuStripInternal.Clone();
            } 
            dataGridViewCell.StateInternal = this.State & ~DataGridViewElementStates.Selected; 
            dataGridViewCell.Tag = this.Tag;
        } 

        /// 
        public virtual object Clone()
        { 
            // SECREVIEW : Late-binding does not represent a security thread, see bug#411899 for more info..
            // 
            DataGridViewCell dataGridViewCell = (DataGridViewCell) System.Activator.CreateInstance(this.GetType()); 
            CloneInternal(dataGridViewCell);
            return dataGridViewCell; 
        }

        internal static int ColorDistance(Color color1, Color color2)
        { 
            int deltaR = color1.R - color2.R;
            int deltaG = color1.G - color2.G; 
            int deltaB = color1.B - color2.B; 
            return deltaR * deltaR + deltaG * deltaG + deltaB * deltaB;
        } 

        internal void ComputeBorderStyleCellStateAndCellBounds(int rowIndex,
            out DataGridViewAdvancedBorderStyle dgvabsEffective,
            out DataGridViewElementStates cellState, 
            out Rectangle cellBounds)
        { 
            Debug.Assert(this.DataGridView != null); 
            bool singleVerticalBorderAdded = !this.DataGridView.RowHeadersVisible && this.DataGridView.AdvancedCellBorderStyle.All == DataGridViewAdvancedCellBorderStyle.Single;
            bool singleHorizontalBorderAdded = !this.DataGridView.ColumnHeadersVisible && this.DataGridView.AdvancedCellBorderStyle.All == DataGridViewAdvancedCellBorderStyle.Single; 
            DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder = new DataGridViewAdvancedBorderStyle();

            if (rowIndex > -1 && this.OwningColumn != null)
            { 
                // Inner cell case
                dgvabsEffective = AdjustCellBorderStyle(this.DataGridView.AdvancedCellBorderStyle, 
                    dataGridViewAdvancedBorderStylePlaceholder, 
                    singleVerticalBorderAdded,
                    singleHorizontalBorderAdded, 
                    rowIndex == this.DataGridView.FirstDisplayedRowIndex /*isFirstDisplayedRow*/,
                    this.ColumnIndex == this.DataGridView.FirstDisplayedColumnIndex /*isFirstDisplayedColumn*/);
                DataGridViewElementStates rowState = this.DataGridView.Rows.GetRowState(rowIndex);
                cellState = this.CellStateFromColumnRowStates(rowState); 
                cellState |= this.State;
            } 
            else if (this.OwningColumn != null) 
            {
                // Column header cell case 
                Debug.Assert(rowIndex == -1);
                Debug.Assert(this is DataGridViewColumnHeaderCell, "if the row index == -1 and we have an owning column this should be a column header cell");
                DataGridViewColumn dataGridViewColumn = this.DataGridView.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None);
                bool isLastVisibleColumn = (dataGridViewColumn != null && dataGridViewColumn.Index == this.ColumnIndex); 
                dgvabsEffective = this.DataGridView.AdjustColumnHeaderBorderStyle(this.DataGridView.AdvancedColumnHeadersBorderStyle,
                    dataGridViewAdvancedBorderStylePlaceholder, 
                    this.ColumnIndex == this.DataGridView.FirstDisplayedColumnIndex, 
                    isLastVisibleColumn);
                cellState = this.OwningColumn.State | this.State; 
            }
            else if (this.OwningRow != null)
            {
                // Row header cell case 
                Debug.Assert(this is DataGridViewRowHeaderCell);
                dgvabsEffective = this.OwningRow.AdjustRowHeaderBorderStyle(this.DataGridView.AdvancedRowHeadersBorderStyle, 
                    dataGridViewAdvancedBorderStylePlaceholder, 
                    singleVerticalBorderAdded,
                    singleHorizontalBorderAdded, 
                    rowIndex == this.DataGridView.FirstDisplayedRowIndex /*isFirstDisplayedRow*/,
                    rowIndex == this.DataGridView.Rows.GetLastRow(DataGridViewElementStates.Visible) /*isLastVisibleRow*/);
                cellState = this.OwningRow.GetState(rowIndex) | this.State;
            } 
            else
            { 
                Debug.Assert(this.OwningColumn == null); 
                Debug.Assert(this.OwningRow == null);
                Debug.Assert(rowIndex == -1); 
                // TopLeft header cell case
                dgvabsEffective = this.DataGridView.AdjustedTopLeftHeaderBorderStyle;
                cellState = this.State;
            } 

            cellBounds = new Rectangle(new Point(0, 0), GetSize(rowIndex)); 
        } 

        internal Rectangle ComputeErrorIconBounds(Rectangle cellValueBounds) 
        {
            if (cellValueBounds.Width >= DATAGRIDVIEWCELL_iconMarginWidth * 2 + DATAGRIDVIEWCELL_iconsWidth &&
                cellValueBounds.Height >= DATAGRIDVIEWCELL_iconMarginHeight * 2 + DATAGRIDVIEWCELL_iconsHeight)
            { 
                Rectangle bmpRect = new Rectangle(this.DataGridView.RightToLeftInternal ?
                                      cellValueBounds.Left + DATAGRIDVIEWCELL_iconMarginWidth : 
                                      cellValueBounds.Right - DATAGRIDVIEWCELL_iconMarginWidth - DATAGRIDVIEWCELL_iconsWidth, 
                                      cellValueBounds.Y + (cellValueBounds.Height - DATAGRIDVIEWCELL_iconsHeight) / 2,
                                      DATAGRIDVIEWCELL_iconsWidth, 
                                      DATAGRIDVIEWCELL_iconsHeight);
                return bmpRect;
            }
            else 
            {
                return Rectangle.Empty; 
            } 
        }
 
        /// 
        [
            SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK.
        ] 
        protected virtual bool ContentClickUnsharesRow(DataGridViewCellEventArgs e)
        { 
            return false; 
        }
 
        internal bool ContentClickUnsharesRowInternal(DataGridViewCellEventArgs e)
        {
            return ContentClickUnsharesRow(e);
        } 

        ///  
        [ 
            SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK.
        ] 
        protected virtual bool ContentDoubleClickUnsharesRow(DataGridViewCellEventArgs e)
        {
            return false;
        } 

        internal bool ContentDoubleClickUnsharesRowInternal(DataGridViewCellEventArgs e) 
        { 
            return ContentDoubleClickUnsharesRow(e);
        } 

        /// 
        protected virtual AccessibleObject CreateAccessibilityInstance()
        { 
            return new DataGridViewCellAccessibleObject(this);
        } 
 
        private void DetachContextMenuStrip(object sender, EventArgs e)
        { 
            this.ContextMenuStripInternal = null;
        }

        ///  
        [
            EditorBrowsable(EditorBrowsableState.Advanced) 
        ] 
        public virtual void DetachEditingControl()
        { 
            DataGridView dgv = this.DataGridView;
            if (dgv == null || dgv.EditingControl == null)
            {
                throw new InvalidOperationException(); 
            }
            if (dgv.EditingControl.ParentInternal != null) 
            { 
                if (dgv.EditingControl.ContainsFocus)
                { 
                    ContainerControl cc = dgv.GetContainerControlInternal() as ContainerControl;
                    if (cc != null && (dgv.EditingControl == cc.ActiveControl || dgv.EditingControl.Contains(cc.ActiveControl)))
                    {
                        dgv.FocusInternal(); 
                    }
                    else 
                    { 
                        // VSWhidbey 481170. We don't want the grid to get the keyboard focus
                        // when the editing control gets parented to the parking window, 
                        // because some other window is in the middle of receiving the focus.
                        UnsafeNativeMethods.SetFocus(new HandleRef(null, IntPtr.Zero));
                    }
                } 
                Debug.Assert(dgv.EditingControl.ParentInternal == dgv.EditingPanel);
                Debug.Assert(dgv.EditingPanel.Controls.Contains(dgv.EditingControl)); 
                dgv.EditingPanel.Controls.Remove(dgv.EditingControl); 
                Debug.Assert(dgv.EditingControl.ParentInternal == null);
            } 
            if (dgv.EditingPanel.ParentInternal != null)
            {
                Debug.Assert(dgv.EditingPanel.ParentInternal == dgv);
                Debug.Assert(dgv.Controls.Contains(dgv.EditingPanel)); 
                ((DataGridView.DataGridViewControlCollection)dgv.Controls).RemoveInternal(dgv.EditingPanel);
                Debug.Assert(dgv.EditingPanel.ParentInternal == null); 
            } 

            Debug.Assert(dgv.EditingControl.ParentInternal == null); 
            Debug.Assert(dgv.EditingPanel.ParentInternal == null);
            Debug.Assert(dgv.EditingPanel.Controls.Count == 0);

            // Since the tooltip is removed when the editing control is shown, 
            // the CurrentMouseLocation is reset to DATAGRIDVIEWCELL_flagAreaNotSet
            // so that the tooltip appears again on mousemove after the editing. 
            this.CurrentMouseLocation = DATAGRIDVIEWCELL_flagAreaNotSet; 
        }
 
        /// 
        public void Dispose()
        {
            Dispose(true); 
            GC.SuppressFinalize(this);
        } 
 
        /// 
        protected virtual void Dispose(bool disposing) 
        {
            if (disposing)
            {
                ContextMenuStrip contextMenuStrip = (ContextMenuStrip)this.ContextMenuStripInternal; 
                if (contextMenuStrip != null)
                { 
                    contextMenuStrip.Disposed -= new EventHandler(DetachContextMenuStrip); 
                }
            } 
        }

        /// 
        [ 
            SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK.
        ] 
        protected virtual bool DoubleClickUnsharesRow(DataGridViewCellEventArgs e) 
        {
            return false; 
        }

        internal bool DoubleClickUnsharesRowInternal(DataGridViewCellEventArgs e)
        { 
            return DoubleClickUnsharesRow(e);
        } 
 
        /// 
        [ 
            SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK.
        ]
        protected virtual bool EnterUnsharesRow(int rowIndex, bool throughMouseClick)
        { 
            return false;
        } 
 
        internal bool EnterUnsharesRowInternal(int rowIndex, bool throughMouseClick)
        { 
            return EnterUnsharesRow(rowIndex, throughMouseClick);
        }

        internal static void FormatPlainText(string s, bool csv, TextWriter output, ref bool escapeApplied) 
        {
            if (s == null) 
            { 
                return;
            } 

            int cb = s.Length;
            for (int i = 0; i < cb; i++)
            { 
                char ch = s[i];
                switch (ch) 
                { 
                    case '"':
                        if (csv) 
                        {
                            output.Write("\"\"");
                            escapeApplied = true;
                        } 
                        else
                        { 
                            output.Write('"'); 
                        }
                        break; 
                    case ',':
                        if (csv)
                        {
                            escapeApplied = true; 
                        }
                        output.Write(','); 
                        break; 
                    case '\t':
                        if (!csv) 
                        {
                            output.Write(' ');
                        }
                        else 
                        {
                            output.Write('\t'); 
                        } 
                        break;
                    default: 
                        output.Write(ch);
                        break;
                }
            } 
            if (escapeApplied)
            { 
                output.Write('"'); // terminating double-quote. 
                // the caller is responsible for inserting the opening double-quote.
            } 
        }

        // Code taken from ASP.NET file xsp\System\Web\httpserverutility.cs
        internal static void FormatPlainTextAsHtml(string s, TextWriter output) 
        {
            if (s == null) 
            { 
                return;
            } 

            int cb = s.Length;
            char prevCh = '\0';
 
            for (int i = 0; i < cb; i++)
            { 
                char ch = s[i]; 
                switch (ch)
                { 
                    case '<':
                        output.Write("<");
                        break;
                    case '>': 
                        output.Write(">");
                        break; 
                    case '"': 
                        output.Write(""");
                        break; 
                    case '&':
                        output.Write("&");
                        break;
                    case ' ': 
                        if (prevCh == ' ')
                        { 
                            output.Write(" "); 
                        }
                        else 
                        {
                            output.Write(ch);
                        }
                        break; 
                    case '\r':
                        // Ignore \r, only handle \n 
                        break; 
                    case '\n':
                        output.Write("
"); break; // default: #if ENTITY_ENCODE_HIGH_ASCII_CHARS // The seemingly arbitrary 160 comes from RFC if (ch >= 160 && ch < 256) { output.Write("&#"); output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo)); output.Write(';'); break; } #endif // ENTITY_ENCODE_HIGH_ASCII_CHARS output.Write(ch); break; } prevCh = ch; } } private static Bitmap GetBitmap(string bitmapName) { Bitmap b = new Bitmap(typeof(DataGridViewCell), bitmapName); b.MakeTransparent(); return b; } /// protected virtual object GetClipboardContent(int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) { if (this.DataGridView == null) { return null; } // Header Cell classes override this implementation - this implementation is only for inner cells if (rowIndex < 0 || rowIndex >= this.DataGridView.Rows.Count) { throw new ArgumentOutOfRangeException("rowIndex"); } // Assuming (like in other places in this class) that the formatted value is independent of the style colors. DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false); object formattedValue = null; if (this.DataGridView.IsSharedCellSelected(this, rowIndex)) { formattedValue = GetEditedFormattedValue(GetValue(rowIndex), rowIndex, ref dataGridViewCellStyle, DataGridViewDataErrorContexts.Formatting | DataGridViewDataErrorContexts.ClipboardContent); } StringBuilder sb = new StringBuilder(64); if (String.Equals(format, DataFormats.Html, StringComparison.OrdinalIgnoreCase)) { if (firstCell) { if (inFirstRow) { sb.Append(""); } sb.Append(""); } sb.Append(""); if (lastCell) { sb.Append(""); if (inLastRow) { sb.Append("
"); if (formattedValue != null) { FormatPlainTextAsHtml(formattedValue.ToString(), new StringWriter(sb, CultureInfo.CurrentCulture)); } else { sb.Append(" "); } sb.Append("
"); } } return sb.ToString(); } else { bool csv = String.Equals(format, DataFormats.CommaSeparatedValue, StringComparison.OrdinalIgnoreCase); if (csv || String.Equals(format, DataFormats.Text, StringComparison.OrdinalIgnoreCase) || String.Equals(format, DataFormats.UnicodeText, StringComparison.OrdinalIgnoreCase)) { if (formattedValue != null) { if (firstCell && lastCell && inFirstRow && inLastRow) { sb.Append(formattedValue.ToString()); } else { bool escapeApplied = false; int insertionPoint = sb.Length; FormatPlainText(formattedValue.ToString(), csv, new StringWriter(sb, CultureInfo.CurrentCulture), ref escapeApplied); if (escapeApplied) { Debug.Assert(csv); sb.Insert(insertionPoint, '"'); } } } if (lastCell) { if (!inLastRow) { sb.Append((char)Keys.Return); sb.Append((char)Keys.LineFeed); } } else { sb.Append(csv ? ',' : (char)Keys.Tab); } return sb.ToString(); } else { return null; } } } internal object GetClipboardContentInternal(int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) { return GetClipboardContent(rowIndex, firstCell, lastCell, inFirstRow, inLastRow, format); } internal ContextMenuStrip GetContextMenuStrip(int rowIndex) { ContextMenuStrip contextMenuStrip = this.ContextMenuStripInternal; if (this.DataGridView != null && (this.DataGridView.VirtualMode || this.DataGridView.DataSource != null)) { contextMenuStrip = this.DataGridView.OnCellContextMenuStripNeeded(this.ColumnIndex, rowIndex, contextMenuStrip); } return contextMenuStrip; } internal void GetContrastedPens(Color baseline, ref Pen darkPen, ref Pen lightPen) { Debug.Assert(this.DataGridView != null); int darkDistance = ColorDistance(baseline, SystemColors.ControlDark); int lightDistance = ColorDistance(baseline, SystemColors.ControlLightLight); if (SystemInformation.HighContrast) { if (darkDistance < DATAGRIDVIEWCELL_highConstrastThreshold) { darkPen = this.DataGridView.GetCachedPen(ControlPaint.DarkDark(baseline)); } else { darkPen = this.DataGridView.GetCachedPen(SystemColors.ControlDark); } if (lightDistance < DATAGRIDVIEWCELL_highConstrastThreshold) { lightPen = this.DataGridView.GetCachedPen(ControlPaint.LightLight(baseline)); } else { lightPen = this.DataGridView.GetCachedPen(SystemColors.ControlLightLight); } } else { if (darkDistance < DATAGRIDVIEWCELL_constrastThreshold) { darkPen = this.DataGridView.GetCachedPen(ControlPaint.Dark(baseline)); } else { darkPen = this.DataGridView.GetCachedPen(SystemColors.ControlDark); } if (lightDistance < DATAGRIDVIEWCELL_constrastThreshold) { lightPen = this.DataGridView.GetCachedPen(ControlPaint.Light(baseline)); } else { lightPen = this.DataGridView.GetCachedPen(SystemColors.ControlLightLight); } } } #if DGV_GDI internal void GetContrastedWindowsPens(Color baseline, ref WindowsPen darkPen, ref WindowsPen lightPen) { Debug.Assert(this.DataGridView != null); int darkDistance = ColorDistance(baseline, SystemColors.ControlDark); int lightDistance = ColorDistance(baseline, SystemColors.ControlLightLight); if (SystemInformation.HighContrast) { if (darkDistance < DATAGRIDVIEWCELL_highConstrastThreshold) { darkPen = this.DataGridView.GetCachedWindowsPen(ControlPaint.DarkDark(baseline)); } else { darkPen = this.DataGridView.GetCachedWindowsPen(SystemColors.ControlDark); } if (lightDistance < DATAGRIDVIEWCELL_highConstrastThreshold) { lightPen = this.DataGridView.GetCachedWindowsPen(ControlPaint.LightLight(baseline)); } else { lightPen = this.DataGridView.GetCachedWindowsPen(SystemColors.ControlLightLight); } } else { if (darkDistance < DATAGRIDVIEWCELL_constrastThreshold) { darkPen = this.DataGridView.GetCachedWindowsPen(ControlPaint.Dark(baseline)); } else { darkPen = this.DataGridView.GetCachedWindowsPen(SystemColors.ControlDark); } if (lightDistance < DATAGRIDVIEWCELL_constrastThreshold) { lightPen = this.DataGridView.GetCachedWindowsPen(ControlPaint.Light(baseline)); } else { lightPen = this.DataGridView.GetCachedWindowsPen(SystemColors.ControlLightLight); } } } #endif // DGV_GDI /// public Rectangle GetContentBounds(int rowIndex) { if (this.DataGridView == null) { return Rectangle.Empty; } DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false /*includeColors*/); return GetContentBounds(this.DataGridView.CachedGraphics, dataGridViewCellStyle, rowIndex); } /// protected virtual Rectangle GetContentBounds(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) { return Rectangle.Empty; } internal object GetEditedFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle dataGridViewCellStyle, DataGridViewDataErrorContexts context) { Debug.Assert(this.DataGridView != null); Point ptCurrentCell = this.DataGridView.CurrentCellAddress; if (this.ColumnIndex == ptCurrentCell.X && rowIndex == ptCurrentCell.Y) { IDataGridViewEditingControl dgvectl = (IDataGridViewEditingControl)this.DataGridView.EditingControl; if (dgvectl != null) { return dgvectl.GetEditingControlFormattedValue(context); } IDataGridViewEditingCell dgvecell = this as IDataGridViewEditingCell; if (dgvecell != null && this.DataGridView.IsCurrentCellInEditMode) { return dgvecell.GetEditingCellFormattedValue(context); } return GetFormattedValue(value, rowIndex, ref dataGridViewCellStyle, null, null, context); } return GetFormattedValue(value, rowIndex, ref dataGridViewCellStyle, null, null, context); } /// public object GetEditedFormattedValue(int rowIndex, DataGridViewDataErrorContexts context) { if (this.DataGridView == null) { return null; } DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false /*includeColors*/); return GetEditedFormattedValue(GetValue(rowIndex), rowIndex, ref dataGridViewCellStyle, context); } internal Rectangle GetErrorIconBounds(int rowIndex) { Debug.Assert(this.DataGridView != null); DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false /*includeColors*/); return GetErrorIconBounds(this.DataGridView.CachedGraphics, dataGridViewCellStyle, rowIndex); } /// protected virtual Rectangle GetErrorIconBounds(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) { return Rectangle.Empty; } /// protected internal virtual string GetErrorText(int rowIndex) { string errorText = string.Empty; object objErrorText = this.Properties.GetObject(PropCellErrorText); if (objErrorText != null) { errorText = (string) objErrorText; } else if (this.DataGridView != null && rowIndex != -1 && rowIndex != this.DataGridView.NewRowIndex && this.OwningColumn != null && this.OwningColumn.IsDataBound && this.DataGridView.DataConnection != null) { errorText = this.DataGridView.DataConnection.GetError(this.OwningColumn.BoundColumnIndex, this.ColumnIndex, rowIndex); } if (this.DataGridView != null && (this.DataGridView.VirtualMode || this.DataGridView.DataSource != null) && this.ColumnIndex >= 0 && rowIndex >= 0) { errorText = this.DataGridView.OnCellErrorTextNeeded(this.ColumnIndex, rowIndex, errorText); } return errorText; } internal object GetFormattedValue(int rowIndex, ref DataGridViewCellStyle cellStyle, DataGridViewDataErrorContexts context) { if (this.DataGridView == null) { return null; } else { return GetFormattedValue(GetValue(rowIndex), rowIndex, ref cellStyle, null, null, context); } } /// [ SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference") // using ref is OK. ] protected virtual object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) { if (this.DataGridView == null) { return null; } DataGridViewCellFormattingEventArgs gdvcfe = this.DataGridView.OnCellFormatting(this.ColumnIndex, rowIndex, value, this.FormattedValueType, cellStyle); cellStyle = gdvcfe.CellStyle; bool formattingApplied = gdvcfe.FormattingApplied; Object formattedValue = gdvcfe.Value; bool checkFormattedValType = true; if (!formattingApplied && this.FormattedValueType != null && (formattedValue == null || !this.FormattedValueType.IsAssignableFrom(formattedValue.GetType()))) { try { formattedValue = Formatter.FormatObject(formattedValue, this.FormattedValueType, valueTypeConverter == null ? this.ValueTypeConverter : valueTypeConverter, /*sourceConverter*/ formattedValueTypeConverter == null ? this.FormattedValueTypeConverter : formattedValueTypeConverter, /*targetConverter*/ cellStyle.Format, cellStyle.FormatProvider, cellStyle.NullValue, cellStyle.DataSourceNullValue); } catch (Exception exception) { if (ClientUtils.IsCriticalException(exception)) { throw; } // Formatting failed, raise OnDataError event. DataGridViewDataErrorEventArgs dgvdee = new DataGridViewDataErrorEventArgs(exception, this.ColumnIndex, rowIndex, context); RaiseDataError(dgvdee); if (dgvdee.ThrowException) { throw dgvdee.Exception; } checkFormattedValType = false; } } if (checkFormattedValType && (formattedValue == null || this.FormattedValueType == null || !this.FormattedValueType.IsAssignableFrom(formattedValue.GetType()))) { if (formattedValue == null && cellStyle.NullValue == null && this.FormattedValueType != null && !typeof(System.ValueType).IsAssignableFrom(this.FormattedValueType)) { // null is an acceptable formatted value return null; } Exception exception = null; if (this.FormattedValueType == null) { exception = new FormatException(SR.GetString(SR.DataGridViewCell_FormattedValueTypeNull)); } else { exception = new FormatException(SR.GetString(SR.DataGridViewCell_FormattedValueHasWrongType)); } DataGridViewDataErrorEventArgs dgvdee = new DataGridViewDataErrorEventArgs(exception, this.ColumnIndex, rowIndex, context); RaiseDataError(dgvdee); if (dgvdee.ThrowException) { throw dgvdee.Exception; } } return formattedValue; } static internal DataGridViewFreeDimension GetFreeDimensionFromConstraint(Size constraintSize) { if (constraintSize.Width < 0 || constraintSize.Height < 0) { throw new ArgumentException(SR.GetString(SR.InvalidArgument, "constraintSize", constraintSize.ToString())); } if (constraintSize.Width == 0) { if (constraintSize.Height == 0) { return DataGridViewFreeDimension.Both; } else { return DataGridViewFreeDimension.Width; } } else { if (constraintSize.Height == 0) { return DataGridViewFreeDimension.Height; } else { throw new ArgumentException(SR.GetString(SR.InvalidArgument, "constraintSize", constraintSize.ToString())); } } } internal int GetHeight(int rowIndex) { if (this.DataGridView == null) { return -1; } Debug.Assert(this.owningRow != null); return this.owningRow.GetHeight(rowIndex); } /// public virtual ContextMenuStrip GetInheritedContextMenuStrip(int rowIndex) { if (this.DataGridView != null) { if (rowIndex < 0 || rowIndex >= this.DataGridView.Rows.Count) { throw new ArgumentOutOfRangeException("rowIndex"); } if (this.ColumnIndex < 0) { throw new InvalidOperationException(); } Debug.Assert(this.ColumnIndex < this.DataGridView.Columns.Count); } ContextMenuStrip contextMenuStrip = GetContextMenuStrip(rowIndex); if (contextMenuStrip != null) { return contextMenuStrip; } if (this.owningRow != null) { contextMenuStrip = this.owningRow.GetContextMenuStrip(rowIndex); if (contextMenuStrip != null) { return contextMenuStrip; } } if (this.owningColumn != null) { contextMenuStrip = this.owningColumn.ContextMenuStrip; if (contextMenuStrip != null) { return contextMenuStrip; } } if (this.DataGridView != null) { return this.DataGridView.ContextMenuStrip; } else { return null; } } /// public virtual DataGridViewElementStates GetInheritedState(int rowIndex) { DataGridViewElementStates state = this.State | DataGridViewElementStates.ResizableSet; if (this.DataGridView == null) { Debug.Assert(this.RowIndex == -1); if (rowIndex != -1) { throw new ArgumentException(SR.GetString(SR.InvalidArgument, "rowIndex", rowIndex.ToString(CultureInfo.CurrentCulture))); } if (this.owningRow != null) { state |= (this.owningRow.GetState(-1) & (DataGridViewElementStates.Frozen | DataGridViewElementStates.ReadOnly | DataGridViewElementStates.Selected | DataGridViewElementStates.Visible)); if (this.owningRow.GetResizable(rowIndex) == DataGridViewTriState.True) { state |= DataGridViewElementStates.Resizable; } } return state; } // Header Cell classes override this implementation - this implementation is only for inner cells if (rowIndex < 0 || rowIndex >= this.DataGridView.Rows.Count) { throw new ArgumentOutOfRangeException("rowIndex"); } Debug.Assert(this.owningColumn != null); Debug.Assert(this.owningRow != null); Debug.Assert(this.ColumnIndex >= 0); if (this.DataGridView.Rows.SharedRow(rowIndex) != this.owningRow) { throw new ArgumentException(SR.GetString(SR.InvalidArgument, "rowIndex", rowIndex.ToString(CultureInfo.CurrentCulture))); } DataGridViewElementStates rowEffectiveState = this.DataGridView.Rows.GetRowState(rowIndex); state |= (rowEffectiveState & (DataGridViewElementStates.ReadOnly | DataGridViewElementStates.Selected)); state |= (this.owningColumn.State & (DataGridViewElementStates.ReadOnly | DataGridViewElementStates.Selected)); if (this.owningRow.GetResizable(rowIndex) == DataGridViewTriState.True || this.owningColumn.Resizable == DataGridViewTriState.True) { state |= DataGridViewElementStates.Resizable; } if (this.owningColumn.Visible && this.owningRow.GetVisible(rowIndex)) { state |= DataGridViewElementStates.Visible; if (this.owningColumn.Displayed && this.owningRow.GetDisplayed(rowIndex)) { state |= DataGridViewElementStates.Displayed; } } if (this.owningColumn.Frozen && this.owningRow.GetFrozen(rowIndex)) { state |= DataGridViewElementStates.Frozen; } #if DEBUG DataGridViewElementStates stateDebug = DataGridViewElementStates.ResizableSet; if (this.Displayed) { stateDebug |= DataGridViewElementStates.Displayed; } if (this.Frozen) { stateDebug |= DataGridViewElementStates.Frozen; } if (this.ReadOnly) { stateDebug |= DataGridViewElementStates.ReadOnly; } if (this.Resizable) { stateDebug |= DataGridViewElementStates.Resizable; } if (this.Selected) { stateDebug |= DataGridViewElementStates.Selected; } if (this.Visible) { stateDebug |= DataGridViewElementStates.Visible; } Debug.Assert(state == stateDebug || this.DataGridView.Rows.SharedRow(rowIndex).Index == -1); #endif return state; } /// public virtual DataGridViewCellStyle GetInheritedStyle(DataGridViewCellStyle inheritedCellStyle, int rowIndex, bool includeColors) { if (this.DataGridView == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridView_CellNeedsDataGridViewForInheritedStyle)); } if (rowIndex < 0 || rowIndex >= this.DataGridView.Rows.Count) { throw new ArgumentOutOfRangeException("rowIndex"); } if (this.ColumnIndex < 0) { throw new InvalidOperationException(); } Debug.Assert(this.ColumnIndex < this.DataGridView.Columns.Count); DataGridViewCellStyle inheritedCellStyleTmp; if (inheritedCellStyle == null) { inheritedCellStyleTmp = this.DataGridView.PlaceholderCellStyle; if (!includeColors) { inheritedCellStyleTmp.BackColor = Color.Empty; inheritedCellStyleTmp.ForeColor = Color.Empty; inheritedCellStyleTmp.SelectionBackColor = Color.Empty; inheritedCellStyleTmp.SelectionForeColor = Color.Empty; } } else { inheritedCellStyleTmp = inheritedCellStyle; } DataGridViewCellStyle cellStyle = null; if (this.HasStyle) { cellStyle = this.Style; Debug.Assert(cellStyle != null); } DataGridViewCellStyle rowStyle = null; if (this.DataGridView.Rows.SharedRow(rowIndex).HasDefaultCellStyle) { rowStyle = this.DataGridView.Rows.SharedRow(rowIndex).DefaultCellStyle; Debug.Assert(rowStyle != null); } DataGridViewCellStyle columnStyle = null; if (this.owningColumn.HasDefaultCellStyle) { columnStyle = this.owningColumn.DefaultCellStyle; Debug.Assert(columnStyle != null); } DataGridViewCellStyle dataGridViewStyle = this.DataGridView.DefaultCellStyle; Debug.Assert(dataGridViewStyle != null); if (includeColors) { if (cellStyle != null && !cellStyle.BackColor.IsEmpty) { inheritedCellStyleTmp.BackColor = cellStyle.BackColor; } else if (rowStyle != null && !rowStyle.BackColor.IsEmpty) { inheritedCellStyleTmp.BackColor = rowStyle.BackColor; } else if (!this.DataGridView.RowsDefaultCellStyle.BackColor.IsEmpty && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.BackColor.IsEmpty)) { inheritedCellStyleTmp.BackColor = this.DataGridView.RowsDefaultCellStyle.BackColor; } else if (rowIndex % 2 == 1 && !this.DataGridView.AlternatingRowsDefaultCellStyle.BackColor.IsEmpty) { inheritedCellStyleTmp.BackColor = this.DataGridView.AlternatingRowsDefaultCellStyle.BackColor; } else if (columnStyle != null && !columnStyle.BackColor.IsEmpty) { inheritedCellStyleTmp.BackColor = columnStyle.BackColor; } else { inheritedCellStyleTmp.BackColor = dataGridViewStyle.BackColor; } if (cellStyle != null && !cellStyle.ForeColor.IsEmpty) { inheritedCellStyleTmp.ForeColor = cellStyle.ForeColor; } else if (rowStyle != null && !rowStyle.ForeColor.IsEmpty) { inheritedCellStyleTmp.ForeColor = rowStyle.ForeColor; } else if (!this.DataGridView.RowsDefaultCellStyle.ForeColor.IsEmpty && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.ForeColor.IsEmpty)) { inheritedCellStyleTmp.ForeColor = this.DataGridView.RowsDefaultCellStyle.ForeColor; } else if (rowIndex % 2 == 1 && !this.DataGridView.AlternatingRowsDefaultCellStyle.ForeColor.IsEmpty) { inheritedCellStyleTmp.ForeColor = this.DataGridView.AlternatingRowsDefaultCellStyle.ForeColor; } else if (columnStyle != null && !columnStyle.ForeColor.IsEmpty) { inheritedCellStyleTmp.ForeColor = columnStyle.ForeColor; } else { inheritedCellStyleTmp.ForeColor = dataGridViewStyle.ForeColor; } if (cellStyle != null && !cellStyle.SelectionBackColor.IsEmpty) { inheritedCellStyleTmp.SelectionBackColor = cellStyle.SelectionBackColor; } else if (rowStyle != null && !rowStyle.SelectionBackColor.IsEmpty) { inheritedCellStyleTmp.SelectionBackColor = rowStyle.SelectionBackColor; } else if (!this.DataGridView.RowsDefaultCellStyle.SelectionBackColor.IsEmpty && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.SelectionBackColor.IsEmpty)) { inheritedCellStyleTmp.SelectionBackColor = this.DataGridView.RowsDefaultCellStyle.SelectionBackColor; } else if (rowIndex % 2 == 1 && !this.DataGridView.AlternatingRowsDefaultCellStyle.SelectionBackColor.IsEmpty) { inheritedCellStyleTmp.SelectionBackColor = this.DataGridView.AlternatingRowsDefaultCellStyle.SelectionBackColor; } else if (columnStyle != null && !columnStyle.SelectionBackColor.IsEmpty) { inheritedCellStyleTmp.SelectionBackColor = columnStyle.SelectionBackColor; } else { inheritedCellStyleTmp.SelectionBackColor = dataGridViewStyle.SelectionBackColor; } if (cellStyle != null && !cellStyle.SelectionForeColor.IsEmpty) { inheritedCellStyleTmp.SelectionForeColor = cellStyle.SelectionForeColor; } else if (rowStyle != null && !rowStyle.SelectionForeColor.IsEmpty) { inheritedCellStyleTmp.SelectionForeColor = rowStyle.SelectionForeColor; } else if (!this.DataGridView.RowsDefaultCellStyle.SelectionForeColor.IsEmpty && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.SelectionForeColor.IsEmpty)) { inheritedCellStyleTmp.SelectionForeColor = this.DataGridView.RowsDefaultCellStyle.SelectionForeColor; } else if (rowIndex % 2 == 1 && !this.DataGridView.AlternatingRowsDefaultCellStyle.SelectionForeColor.IsEmpty) { inheritedCellStyleTmp.SelectionForeColor = this.DataGridView.AlternatingRowsDefaultCellStyle.SelectionForeColor; } else if (columnStyle != null && !columnStyle.SelectionForeColor.IsEmpty) { inheritedCellStyleTmp.SelectionForeColor = columnStyle.SelectionForeColor; } else { inheritedCellStyleTmp.SelectionForeColor = dataGridViewStyle.SelectionForeColor; } } if (cellStyle != null && cellStyle.Font != null) { inheritedCellStyleTmp.Font = cellStyle.Font; } else if (rowStyle != null && rowStyle.Font != null) { inheritedCellStyleTmp.Font = rowStyle.Font; } else if (this.DataGridView.RowsDefaultCellStyle.Font != null && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.Font == null)) { inheritedCellStyleTmp.Font = this.DataGridView.RowsDefaultCellStyle.Font; } else if (rowIndex % 2 == 1 && this.DataGridView.AlternatingRowsDefaultCellStyle.Font != null) { inheritedCellStyleTmp.Font = this.DataGridView.AlternatingRowsDefaultCellStyle.Font; } else if (columnStyle != null && columnStyle.Font != null) { inheritedCellStyleTmp.Font = columnStyle.Font; } else { inheritedCellStyleTmp.Font = dataGridViewStyle.Font; } if (cellStyle != null && !cellStyle.IsNullValueDefault) { inheritedCellStyleTmp.NullValue = cellStyle.NullValue; } else if (rowStyle != null && !rowStyle.IsNullValueDefault) { inheritedCellStyleTmp.NullValue = rowStyle.NullValue; } else if (!this.DataGridView.RowsDefaultCellStyle.IsNullValueDefault && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.IsNullValueDefault)) { inheritedCellStyleTmp.NullValue = this.DataGridView.RowsDefaultCellStyle.NullValue; } else if (rowIndex % 2 == 1 && !this.DataGridView.AlternatingRowsDefaultCellStyle.IsNullValueDefault) { inheritedCellStyleTmp.NullValue = this.DataGridView.AlternatingRowsDefaultCellStyle.NullValue; } else if (columnStyle != null && !columnStyle.IsNullValueDefault) { inheritedCellStyleTmp.NullValue = columnStyle.NullValue; } else { inheritedCellStyleTmp.NullValue = dataGridViewStyle.NullValue; } if (cellStyle != null && !cellStyle.IsDataSourceNullValueDefault) { inheritedCellStyleTmp.DataSourceNullValue = cellStyle.DataSourceNullValue; } else if (rowStyle != null && !rowStyle.IsDataSourceNullValueDefault) { inheritedCellStyleTmp.DataSourceNullValue = rowStyle.DataSourceNullValue; } else if (!this.DataGridView.RowsDefaultCellStyle.IsDataSourceNullValueDefault && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.IsDataSourceNullValueDefault)) { inheritedCellStyleTmp.DataSourceNullValue = this.DataGridView.RowsDefaultCellStyle.DataSourceNullValue; } else if (rowIndex % 2 == 1 && !this.DataGridView.AlternatingRowsDefaultCellStyle.IsDataSourceNullValueDefault) { inheritedCellStyleTmp.DataSourceNullValue = this.DataGridView.AlternatingRowsDefaultCellStyle.DataSourceNullValue; } else if (columnStyle != null && !columnStyle.IsDataSourceNullValueDefault) { inheritedCellStyleTmp.DataSourceNullValue = columnStyle.DataSourceNullValue; } else { inheritedCellStyleTmp.DataSourceNullValue = dataGridViewStyle.DataSourceNullValue; } if (cellStyle != null && cellStyle.Format.Length != 0) { inheritedCellStyleTmp.Format = cellStyle.Format; } else if (rowStyle != null && rowStyle.Format.Length != 0) { inheritedCellStyleTmp.Format = rowStyle.Format; } else if (this.DataGridView.RowsDefaultCellStyle.Format.Length != 0 && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.Format.Length == 0)) { inheritedCellStyleTmp.Format = this.DataGridView.RowsDefaultCellStyle.Format; } else if (rowIndex % 2 == 1 && this.DataGridView.AlternatingRowsDefaultCellStyle.Format.Length != 0) { inheritedCellStyleTmp.Format = this.DataGridView.AlternatingRowsDefaultCellStyle.Format; } else if (columnStyle != null && columnStyle.Format.Length != 0) { inheritedCellStyleTmp.Format = columnStyle.Format; } else { inheritedCellStyleTmp.Format = dataGridViewStyle.Format; } if (cellStyle != null && !cellStyle.IsFormatProviderDefault) { inheritedCellStyleTmp.FormatProvider = cellStyle.FormatProvider; } else if (rowStyle != null && !rowStyle.IsFormatProviderDefault) { inheritedCellStyleTmp.FormatProvider = rowStyle.FormatProvider; } else if (!this.DataGridView.RowsDefaultCellStyle.IsFormatProviderDefault && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.IsFormatProviderDefault)) { inheritedCellStyleTmp.FormatProvider = this.DataGridView.RowsDefaultCellStyle.FormatProvider; } else if (rowIndex % 2 == 1 && !this.DataGridView.AlternatingRowsDefaultCellStyle.IsFormatProviderDefault) { inheritedCellStyleTmp.FormatProvider = this.DataGridView.AlternatingRowsDefaultCellStyle.FormatProvider; } else if (columnStyle != null && !columnStyle.IsFormatProviderDefault) { inheritedCellStyleTmp.FormatProvider = columnStyle.FormatProvider; } else { inheritedCellStyleTmp.FormatProvider = dataGridViewStyle.FormatProvider; } if (cellStyle != null && cellStyle.Alignment != DataGridViewContentAlignment.NotSet) { inheritedCellStyleTmp.AlignmentInternal = cellStyle.Alignment; } else if (rowStyle != null && rowStyle.Alignment != DataGridViewContentAlignment.NotSet) { inheritedCellStyleTmp.AlignmentInternal = rowStyle.Alignment; } else if (this.DataGridView.RowsDefaultCellStyle.Alignment != DataGridViewContentAlignment.NotSet && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.Alignment == DataGridViewContentAlignment.NotSet)) { inheritedCellStyleTmp.AlignmentInternal = this.DataGridView.RowsDefaultCellStyle.Alignment; } else if (rowIndex % 2 == 1 && this.DataGridView.AlternatingRowsDefaultCellStyle.Alignment != DataGridViewContentAlignment.NotSet) { inheritedCellStyleTmp.AlignmentInternal = this.DataGridView.AlternatingRowsDefaultCellStyle.Alignment; } else if (columnStyle != null && columnStyle.Alignment != DataGridViewContentAlignment.NotSet) { inheritedCellStyleTmp.AlignmentInternal = columnStyle.Alignment; } else { Debug.Assert(dataGridViewStyle.Alignment != DataGridViewContentAlignment.NotSet); inheritedCellStyleTmp.AlignmentInternal = dataGridViewStyle.Alignment; } if (cellStyle != null && cellStyle.WrapMode != DataGridViewTriState.NotSet) { inheritedCellStyleTmp.WrapModeInternal = cellStyle.WrapMode; } else if (rowStyle != null && rowStyle.WrapMode != DataGridViewTriState.NotSet) { inheritedCellStyleTmp.WrapModeInternal = rowStyle.WrapMode; } else if (this.DataGridView.RowsDefaultCellStyle.WrapMode != DataGridViewTriState.NotSet && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.WrapMode == DataGridViewTriState.NotSet)) { inheritedCellStyleTmp.WrapModeInternal = this.DataGridView.RowsDefaultCellStyle.WrapMode; } else if (rowIndex % 2 == 1 && this.DataGridView.AlternatingRowsDefaultCellStyle.WrapMode != DataGridViewTriState.NotSet) { inheritedCellStyleTmp.WrapModeInternal = this.DataGridView.AlternatingRowsDefaultCellStyle.WrapMode; } else if (columnStyle != null && columnStyle.WrapMode != DataGridViewTriState.NotSet) { inheritedCellStyleTmp.WrapModeInternal = columnStyle.WrapMode; } else { Debug.Assert(dataGridViewStyle.WrapMode != DataGridViewTriState.NotSet); inheritedCellStyleTmp.WrapModeInternal = dataGridViewStyle.WrapMode; } if (cellStyle != null && cellStyle.Tag != null) { inheritedCellStyleTmp.Tag = cellStyle.Tag; } else if (rowStyle != null && rowStyle.Tag != null) { inheritedCellStyleTmp.Tag = rowStyle.Tag; } else if (this.DataGridView.RowsDefaultCellStyle.Tag != null && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.Tag == null)) { inheritedCellStyleTmp.Tag = this.DataGridView.RowsDefaultCellStyle.Tag; } else if (rowIndex % 2 == 1 && this.DataGridView.AlternatingRowsDefaultCellStyle.Tag != null) { inheritedCellStyleTmp.Tag = this.DataGridView.AlternatingRowsDefaultCellStyle.Tag; } else if (columnStyle != null && columnStyle.Tag != null) { inheritedCellStyleTmp.Tag = columnStyle.Tag; } else { inheritedCellStyleTmp.Tag = dataGridViewStyle.Tag; } if (cellStyle != null && cellStyle.Padding != Padding.Empty) { inheritedCellStyleTmp.PaddingInternal = cellStyle.Padding; } else if (rowStyle != null && rowStyle.Padding != Padding.Empty) { inheritedCellStyleTmp.PaddingInternal = rowStyle.Padding; } else if (this.DataGridView.RowsDefaultCellStyle.Padding != Padding.Empty && (rowIndex % 2 == 0 || this.DataGridView.AlternatingRowsDefaultCellStyle.Padding == Padding.Empty)) { inheritedCellStyleTmp.PaddingInternal = this.DataGridView.RowsDefaultCellStyle.Padding; } else if (rowIndex % 2 == 1 && this.DataGridView.AlternatingRowsDefaultCellStyle.Padding != Padding.Empty) { inheritedCellStyleTmp.PaddingInternal = this.DataGridView.AlternatingRowsDefaultCellStyle.Padding; } else if (columnStyle != null && columnStyle.Padding != Padding.Empty) { inheritedCellStyleTmp.PaddingInternal = columnStyle.Padding; } else { inheritedCellStyleTmp.PaddingInternal = dataGridViewStyle.Padding; } return inheritedCellStyleTmp; } internal DataGridViewCellStyle GetInheritedStyleInternal(int rowIndex) { return GetInheritedStyle(null, rowIndex, true /*includeColors*/); } internal int GetPreferredHeight(int rowIndex, int width) { Debug.Assert(width > 0); if (this.DataGridView == null) { return -1; } DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false); return GetPreferredSize(this.DataGridView.CachedGraphics, dataGridViewCellStyle, rowIndex, new Size(width, 0)).Height; } internal Size GetPreferredSize(int rowIndex) { if (this.DataGridView == null) { return new Size(-1, -1); } DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false); return GetPreferredSize(this.DataGridView.CachedGraphics, dataGridViewCellStyle, rowIndex, Size.Empty); } /// protected virtual Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) { return new Size(-1, -1); } internal static int GetPreferredTextHeight(Graphics g, bool rightToLeft, string text, DataGridViewCellStyle cellStyle, int maxWidth, out bool widthTruncated) { Debug.Assert(maxWidth > 0); TextFormatFlags flags = DataGridViewUtilities.ComputeTextFormatFlagsForCellStyleAlignment(rightToLeft, cellStyle.Alignment, cellStyle.WrapMode); if (cellStyle.WrapMode == DataGridViewTriState.True) { return DataGridViewCell.MeasureTextHeight(g, text, cellStyle.Font, maxWidth, flags, out widthTruncated); } else { Size size = DataGridViewCell.MeasureTextSize(g, text, cellStyle.Font, flags); widthTruncated = size.Width > maxWidth; return size.Height; } } internal int GetPreferredWidth(int rowIndex, int height) { Debug.Assert(height > 0); if (this.DataGridView == null) { return -1; } DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false); return GetPreferredSize(this.DataGridView.CachedGraphics, dataGridViewCellStyle, rowIndex, new Size(0, height)).Width; } /// protected virtual Size GetSize(int rowIndex) { if (this.DataGridView == null) { return new Size(-1, -1); } if (rowIndex == -1) { throw new InvalidOperationException(SR.GetString(SR.DataGridView_InvalidPropertyGetOnSharedCell, "Size")); } Debug.Assert(this.owningColumn != null); Debug.Assert(this.owningRow != null); return new Size(this.owningColumn.Thickness, this.owningRow.GetHeight(rowIndex)); } private string GetToolTipText(int rowIndex) { string toolTipText = this.ToolTipTextInternal; if (this.DataGridView != null && (this.DataGridView.VirtualMode || this.DataGridView.DataSource != null)) { toolTipText = this.DataGridView.OnCellToolTipTextNeeded(this.ColumnIndex, rowIndex, toolTipText); } return toolTipText; } /// protected virtual object GetValue(int rowIndex) { DataGridView dataGridView = this.DataGridView; if (dataGridView != null) { if (rowIndex < 0 || rowIndex >= dataGridView.Rows.Count) { throw new ArgumentOutOfRangeException("rowIndex"); } if (this.ColumnIndex < 0) { throw new InvalidOperationException(); } Debug.Assert(this.ColumnIndex < dataGridView.Columns.Count); } if (dataGridView == null || (dataGridView.AllowUserToAddRowsInternal && rowIndex > -1 && rowIndex == dataGridView.NewRowIndex && rowIndex != dataGridView.CurrentCellAddress.Y) || (!dataGridView.VirtualMode && this.OwningColumn != null && !this.OwningColumn.IsDataBound) || rowIndex == -1 || this.ColumnIndex == -1) { return this.Properties.GetObject(PropCellValue); } else if (this.OwningColumn != null && this.OwningColumn.IsDataBound) { DataGridView.DataGridViewDataConnection dataConnection = dataGridView.DataConnection; if (dataConnection == null) { return null; } else if (dataConnection.CurrencyManager.Count <= rowIndex) { return this.Properties.GetObject(PropCellValue); } else { return dataConnection.GetValue(this.OwningColumn.BoundColumnIndex, this.ColumnIndex, rowIndex); } } else { Debug.Assert(rowIndex >= 0); Debug.Assert(this.ColumnIndex >= 0); return dataGridView.OnCellValueNeeded(this.ColumnIndex, rowIndex); } } internal object GetValueInternal(int rowIndex) { return GetValue(rowIndex); } /// [ EditorBrowsable(EditorBrowsableState.Advanced) ] public virtual void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { DataGridView dgv = this.DataGridView; if (dgv == null || dgv.EditingControl == null) { throw new InvalidOperationException(); } // Only add the control to the dataGridView's children if this hasn't been done yet since // InitializeEditingControl can be called several times. if (dgv.EditingControl.ParentInternal == null) { // Add editing control to the dataGridView hierarchy dgv.EditingControl.CausesValidation = dgv.CausesValidation; dgv.EditingPanel.CausesValidation = dgv.CausesValidation; dgv.EditingControl.Visible = true; Debug.Assert(!dgv.EditingPanel.ContainsFocus); dgv.EditingPanel.Visible = false; Debug.Assert(dgv.EditingPanel.ParentInternal == null); dgv.Controls.Add(dgv.EditingPanel); dgv.EditingPanel.Controls.Add(dgv.EditingControl); Debug.Assert(dgv.IsSharedCellVisible(this, rowIndex)); } Debug.Assert(dgv.EditingControl.ParentInternal == dgv.EditingPanel); Debug.Assert(dgv.EditingPanel.ParentInternal == dgv); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool KeyDownUnsharesRow(KeyEventArgs e, int rowIndex) { return false; } internal bool KeyDownUnsharesRowInternal(KeyEventArgs e, int rowIndex) { return KeyDownUnsharesRow(e, rowIndex); } /// public virtual bool KeyEntersEditMode(KeyEventArgs e) { return false; } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool KeyPressUnsharesRow(KeyPressEventArgs e, int rowIndex) { return false; } internal bool KeyPressUnsharesRowInternal(KeyPressEventArgs e, int rowIndex) { return KeyPressUnsharesRow(e, rowIndex); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool KeyUpUnsharesRow(KeyEventArgs e, int rowIndex) { return false; } internal bool KeyUpUnsharesRowInternal(KeyEventArgs e, int rowIndex) { return KeyUpUnsharesRow(e, rowIndex); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool LeaveUnsharesRow(int rowIndex, bool throughMouseClick) { return false; } internal bool LeaveUnsharesRowInternal(int rowIndex, bool throughMouseClick) { return LeaveUnsharesRow(rowIndex, throughMouseClick); } /// [ EditorBrowsable(EditorBrowsableState.Advanced) ] public static int MeasureTextHeight(Graphics graphics, string text, Font font, int maxWidth, TextFormatFlags flags) { bool widthTruncated; return DataGridViewCell.MeasureTextHeight(graphics, text, font, maxWidth, flags, out widthTruncated); } /// [ EditorBrowsable(EditorBrowsableState.Advanced), SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters"), // We don't want to use IDeviceContext here. SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters") // out param OK here. ] public static int MeasureTextHeight(Graphics graphics, string text, Font font, int maxWidth, TextFormatFlags flags, out bool widthTruncated) { if (graphics == null) { throw new ArgumentNullException("graphics"); } if (font == null) { throw new ArgumentNullException("font"); } if (maxWidth <= 0) { throw new ArgumentOutOfRangeException("maxWidth", SR.GetString(SR.InvalidLowBoundArgument, "maxWidth", (maxWidth).ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture))); } if (!DataGridViewUtilities.ValidTextFormatFlags(flags)) { throw new InvalidEnumArgumentException("flags", (int) flags, typeof(TextFormatFlags)); } flags &= textFormatSupportedFlags; // VSWhidbey 495922: dont use passed in graphics so we can optimze measurement Size requiredSize = TextRenderer.MeasureText(text, font, new Size(maxWidth, System.Int32.MaxValue), flags); widthTruncated = (requiredSize.Width > maxWidth); return requiredSize.Height; } /// [ EditorBrowsable(EditorBrowsableState.Advanced) ] public static Size MeasureTextPreferredSize(Graphics graphics, string text, Font font, float maxRatio, TextFormatFlags flags) { if (graphics == null) { throw new ArgumentNullException("graphics"); } if (font == null) { throw new ArgumentNullException("font"); } if (maxRatio <= 0.0F) { throw new ArgumentOutOfRangeException("maxRatio", SR.GetString(SR.InvalidLowBoundArgument, "maxRatio", (maxRatio).ToString(CultureInfo.CurrentCulture), "0.0")); } if (!DataGridViewUtilities.ValidTextFormatFlags(flags)) { throw new InvalidEnumArgumentException("flags", (int) flags, typeof(TextFormatFlags)); } if (string.IsNullOrEmpty(text)) { return new Size(0, 0); } Size textOneLineSize = DataGridViewCell.MeasureTextSize(graphics, text, font, flags); if ((float)(textOneLineSize.Width / textOneLineSize.Height) <= maxRatio) { return textOneLineSize; } flags &= textFormatSupportedFlags; float maxWidth = (float) (textOneLineSize.Width * textOneLineSize.Width) / (float) textOneLineSize.Height / maxRatio * 1.1F; Size textSize; do { // VSWhidbey 495922: dont use passed in graphics so we can optimze measurement textSize = TextRenderer.MeasureText(text, font, new Size((int)maxWidth, System.Int32.MaxValue), flags); if ((float)(textSize.Width / textSize.Height) <= maxRatio || textSize.Width > (int)maxWidth) { return textSize; } maxWidth = (float)textSize.Width * 0.9F; } while (maxWidth > 1.0F); return textSize; } /// [ EditorBrowsable(EditorBrowsableState.Advanced), SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters") // We don't want to use IDeviceContext here. ] public static Size MeasureTextSize(Graphics graphics, string text, Font font, TextFormatFlags flags) { if (graphics == null) { throw new ArgumentNullException("graphics"); } if (font == null) { throw new ArgumentNullException("font"); } if (!DataGridViewUtilities.ValidTextFormatFlags(flags)) { throw new InvalidEnumArgumentException("flags", (int) flags, typeof(TextFormatFlags)); } flags &= textFormatSupportedFlags; // VSWhidbey 495922: dont use passed in graphics so we can optimze measurement return TextRenderer.MeasureText(text, font, new Size(System.Int32.MaxValue, System.Int32.MaxValue), flags); } /// [ EditorBrowsable(EditorBrowsableState.Advanced) ] public static int MeasureTextWidth(Graphics graphics, string text, Font font, int maxHeight, TextFormatFlags flags) { if (maxHeight <= 0) { throw new ArgumentOutOfRangeException("maxHeight", SR.GetString(SR.InvalidLowBoundArgument, "maxHeight", (maxHeight).ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture))); } Size oneLineSize = DataGridViewCell.MeasureTextSize(graphics, text, font, flags); if (oneLineSize.Height >= maxHeight || (flags & TextFormatFlags.SingleLine) != 0) { return oneLineSize.Width; } else { flags &= textFormatSupportedFlags; int lastFittingWidth = oneLineSize.Width; float maxWidth = (float) lastFittingWidth * 0.9F; Size textSize; do { // VSWhidbey 495922: dont use passed in graphics so we can optimze measurement textSize = TextRenderer.MeasureText(text, font, new Size((int)maxWidth, maxHeight), flags); if (textSize.Height > maxHeight || textSize.Width > (int)maxWidth) { return lastFittingWidth; } else { lastFittingWidth = (int)maxWidth; maxWidth = (float)textSize.Width * 0.9F; } } while (maxWidth > 1.0F); Debug.Assert(textSize.Height <= maxHeight); return lastFittingWidth; } } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool MouseClickUnsharesRow(DataGridViewCellMouseEventArgs e) { return false; } internal bool MouseClickUnsharesRowInternal(DataGridViewCellMouseEventArgs e) { return MouseClickUnsharesRow(e); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool MouseDoubleClickUnsharesRow(DataGridViewCellMouseEventArgs e) { return false; } internal bool MouseDoubleClickUnsharesRowInternal(DataGridViewCellMouseEventArgs e) { return MouseDoubleClickUnsharesRow(e); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool MouseDownUnsharesRow(DataGridViewCellMouseEventArgs e) { return false; } internal bool MouseDownUnsharesRowInternal(DataGridViewCellMouseEventArgs e) { return MouseDownUnsharesRow(e); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool MouseEnterUnsharesRow(int rowIndex) { return false; } internal bool MouseEnterUnsharesRowInternal(int rowIndex) { return MouseEnterUnsharesRow(rowIndex); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool MouseLeaveUnsharesRow(int rowIndex) { return false; } internal bool MouseLeaveUnsharesRowInternal(int rowIndex) { return MouseLeaveUnsharesRow(rowIndex); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool MouseMoveUnsharesRow(DataGridViewCellMouseEventArgs e) { return false; } internal bool MouseMoveUnsharesRowInternal(DataGridViewCellMouseEventArgs e) { return MouseMoveUnsharesRow(e); } /// [ SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly") // Unshares is OK. ] protected virtual bool MouseUpUnsharesRow(DataGridViewCellMouseEventArgs e) { return false; } internal bool MouseUpUnsharesRowInternal(DataGridViewCellMouseEventArgs e) { return MouseUpUnsharesRow(e); } private void OnCellDataAreaMouseEnterInternal(int rowIndex) { Debug.Assert(this.DataGridView != null); if (!this.DataGridView.ShowCellToolTips) { return; } // Don't show a tooltip for edited cells with an editing control Point ptCurrentCell = this.DataGridView.CurrentCellAddress; if (ptCurrentCell.X != -1 && ptCurrentCell.X == this.ColumnIndex && ptCurrentCell.Y == rowIndex && this.DataGridView.EditingControl != null) { Debug.Assert(this.DataGridView.IsCurrentCellInEditMode); return; } // get the tool tip string string toolTipText = GetToolTipText(rowIndex); if (String.IsNullOrEmpty(toolTipText)) { if (this.FormattedValueType == stringType) { if (rowIndex != -1 && this.OwningColumn != null) { int width = GetPreferredWidth(rowIndex, this.OwningRow.Height); int height = GetPreferredHeight(rowIndex, this.OwningColumn.Width); if (this.OwningColumn.Width < width || this.OwningRow.Height < height) { DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false /*includeColors*/); string editedFormattedValue = GetEditedFormattedValue(GetValue(rowIndex), rowIndex, ref dataGridViewCellStyle, DataGridViewDataErrorContexts.Display) as string; if (!string.IsNullOrEmpty(editedFormattedValue)) { toolTipText = TruncateToolTipText(editedFormattedValue); } } } else if ((rowIndex != -1 && this.OwningRow != null && this.DataGridView.RowHeadersVisible && this.DataGridView.RowHeadersWidth > 0 && this.OwningColumn == null) || rowIndex == -1) { // we are on a header cell. Debug.Assert(this is DataGridViewHeaderCell); string stringValue = GetValue(rowIndex) as string; if (!string.IsNullOrEmpty(stringValue)) { DataGridViewCellStyle dataGridViewCellStyle = GetInheritedStyle(null, rowIndex, false); Rectangle contentBounds = GetContentBounds(this.DataGridView.CachedGraphics, dataGridViewCellStyle, rowIndex); bool widthTruncated = false; int preferredHeight = 0; if (contentBounds.Width > 0) { preferredHeight = DataGridViewCell.GetPreferredTextHeight(this.DataGridView.CachedGraphics, this.DataGridView.RightToLeftInternal, stringValue, dataGridViewCellStyle, contentBounds.Width, out widthTruncated); } else { widthTruncated = true; } if (preferredHeight > contentBounds.Height || widthTruncated) { toolTipText = TruncateToolTipText(stringValue); } } } } } else if (this.DataGridView.IsRestricted) { // In semi trust (demand for AllWindows fails), we truncate the tooltip at 256 if it exceeds 288 characters. toolTipText = TruncateToolTipText(toolTipText); } if (!String.IsNullOrEmpty(toolTipText)) { this.DataGridView.ActivateToolTip(true /*activate*/, toolTipText, this.ColumnIndex, rowIndex); } // for debugging // Console.WriteLine("OnCellDATA_AreaMouseENTER. ToolTipText : " + toolTipText); } private void OnCellDataAreaMouseLeaveInternal() { this.DataGridView.ActivateToolTip(false /*activate*/, string.Empty, -1, -1); // for debugging // Console.WriteLine("OnCellDATA_AreaMouseLEAVE"); } private void OnCellErrorAreaMouseEnterInternal(int rowIndex) { string errorText = GetErrorText(rowIndex); Debug.Assert(!String.IsNullOrEmpty(errorText), "if we entered the cell error area then an error was painted, so we should have an error"); this.DataGridView.ActivateToolTip(true /*activate*/, errorText, this.ColumnIndex, rowIndex); // for debugging // Console.WriteLine("OnCellERROR_AreaMouseENTER. ErrorText : " + errorText); } private void OnCellErrorAreaMouseLeaveInternal() { this.DataGridView.ActivateToolTip(false /*activate*/, string.Empty, -1, -1); // for debugging // Console.WriteLine("OnCellERROR_AreaMouseLEAVE"); } /// protected virtual void OnClick(DataGridViewCellEventArgs e) { } internal void OnClickInternal(DataGridViewCellEventArgs e) { OnClick(e); } internal void OnCommonChange() { if (this.DataGridView != null && !this.DataGridView.IsDisposed && !this.DataGridView.Disposing) { if (this.RowIndex == -1) { // Invalidate and autosize column this.DataGridView.OnColumnCommonChange(this.ColumnIndex); } else { // Invalidate and autosize cell this.DataGridView.OnCellCommonChange(this.ColumnIndex, this.RowIndex); } } } /// protected virtual void OnContentClick(DataGridViewCellEventArgs e) { } internal void OnContentClickInternal(DataGridViewCellEventArgs e) { OnContentClick(e); } /// protected virtual void OnContentDoubleClick(DataGridViewCellEventArgs e) { } internal void OnContentDoubleClickInternal(DataGridViewCellEventArgs e) { OnContentDoubleClick(e); } /// protected virtual void OnDoubleClick(DataGridViewCellEventArgs e) { } internal void OnDoubleClickInternal(DataGridViewCellEventArgs e) { OnDoubleClick(e); } /// protected virtual void OnEnter(int rowIndex, bool throughMouseClick) { } internal void OnEnterInternal(int rowIndex, bool throughMouseClick) { OnEnter(rowIndex, throughMouseClick); } internal void OnKeyDownInternal(KeyEventArgs e, int rowIndex) { OnKeyDown(e, rowIndex); } /// protected virtual void OnKeyDown(KeyEventArgs e, int rowIndex) { } internal void OnKeyPressInternal(KeyPressEventArgs e, int rowIndex) { OnKeyPress(e, rowIndex); } /// protected virtual void OnKeyPress(KeyPressEventArgs e, int rowIndex) { } /// protected virtual void OnKeyUp(KeyEventArgs e, int rowIndex) { } /// internal void OnKeyUpInternal(KeyEventArgs e, int rowIndex) { OnKeyUp(e, rowIndex); } /// protected virtual void OnLeave(int rowIndex, bool throughMouseClick) { } internal void OnLeaveInternal(int rowIndex, bool throughMouseClick) { OnLeave(rowIndex, throughMouseClick); } /// protected virtual void OnMouseClick(DataGridViewCellMouseEventArgs e) { } internal void OnMouseClickInternal(DataGridViewCellMouseEventArgs e) { OnMouseClick(e); } /// protected virtual void OnMouseDoubleClick(DataGridViewCellMouseEventArgs e) { } internal void OnMouseDoubleClickInternal(DataGridViewCellMouseEventArgs e) { OnMouseDoubleClick(e); } /// protected virtual void OnMouseDown(DataGridViewCellMouseEventArgs e) { } internal void OnMouseDownInternal(DataGridViewCellMouseEventArgs e) { this.DataGridView.CellMouseDownInContentBounds = GetContentBounds(e.RowIndex).Contains(e.X, e.Y); if (((this.ColumnIndex < 0 || e.RowIndex < 0) && this.DataGridView.ApplyVisualStylesToHeaderCells) || ((this.ColumnIndex >= 0 && e.RowIndex >= 0) && this.DataGridView.ApplyVisualStylesToInnerCells)) { DataGridView.InvalidateCell(this.ColumnIndex, e.RowIndex); } OnMouseDown(e); } /// protected virtual void OnMouseEnter(int rowIndex) { } internal void OnMouseEnterInternal(int rowIndex) { OnMouseEnter(rowIndex); } /// protected virtual void OnMouseLeave(int rowIndex) { } internal void OnMouseLeaveInternal(int rowIndex) { switch (this.CurrentMouseLocation) { case DATAGRIDVIEWCELL_flagDataArea: OnCellDataAreaMouseLeaveInternal(); break; case DATAGRIDVIEWCELL_flagErrorArea: OnCellErrorAreaMouseLeaveInternal(); break; case DATAGRIDVIEWCELL_flagAreaNotSet: // [....]: there seems to be a bug in setting the HorizontalOffset when scrolling // Debug.Assert(false, "if we leave the cell we should already have set the CurrentMouseLocation to Data Area or Error Area"); break; default: Debug.Assert(false, "there are only three possible choices for the CurrentMouseLocation"); break; } this.CurrentMouseLocation = DATAGRIDVIEWCELL_flagAreaNotSet; OnMouseLeave(rowIndex); } /// protected virtual void OnMouseMove(DataGridViewCellMouseEventArgs e) { } internal void OnMouseMoveInternal(DataGridViewCellMouseEventArgs e) { byte mouseLocation = this.CurrentMouseLocation; UpdateCurrentMouseLocation(e); Debug.Assert(this.CurrentMouseLocation != DATAGRIDVIEWCELL_flagAreaNotSet); switch (mouseLocation) { case DATAGRIDVIEWCELL_flagAreaNotSet: if (this.CurrentMouseLocation == DATAGRIDVIEWCELL_flagDataArea) { OnCellDataAreaMouseEnterInternal(e.RowIndex); } else { OnCellErrorAreaMouseEnterInternal(e.RowIndex); } break; case DATAGRIDVIEWCELL_flagDataArea: if (this.CurrentMouseLocation == DATAGRIDVIEWCELL_flagErrorArea) { OnCellDataAreaMouseLeaveInternal(); OnCellErrorAreaMouseEnterInternal(e.RowIndex); } break; case DATAGRIDVIEWCELL_flagErrorArea: if (this.CurrentMouseLocation == DATAGRIDVIEWCELL_flagDataArea) { OnCellErrorAreaMouseLeaveInternal(); OnCellDataAreaMouseEnterInternal(e.RowIndex); } break; default: Debug.Fail("there are only three choices for CurrentMouseLocation"); break; } OnMouseMove(e); } /// protected virtual void OnMouseUp(DataGridViewCellMouseEventArgs e) { } internal void OnMouseUpInternal(DataGridViewCellMouseEventArgs e) { int x = e.X; int y = e.Y; if (((this.ColumnIndex < 0 || e.RowIndex < 0) && this.DataGridView.ApplyVisualStylesToHeaderCells) || ((this.ColumnIndex >= 0 && e.RowIndex >= 0) && this.DataGridView.ApplyVisualStylesToInnerCells)) { this.DataGridView.InvalidateCell(this.ColumnIndex, e.RowIndex); } if (e.Button == MouseButtons.Left && GetContentBounds(e.RowIndex).Contains(x, y)) { this.DataGridView.OnCommonCellContentClick(e.ColumnIndex, e.RowIndex, e.Clicks > 1); } if (this.DataGridView != null && e.ColumnIndex < this.DataGridView.Columns.Count && e.RowIndex < this.DataGridView.Rows.Count) { OnMouseUp(e); } } /// protected override void OnDataGridViewChanged() { if (this.HasStyle) { if (this.DataGridView == null) { this.Style.RemoveScope(DataGridViewCellStyleScopes.Cell); } else { this.Style.AddScope(this.DataGridView, DataGridViewCellStyleScopes.Cell); } } base.OnDataGridViewChanged(); } /// protected virtual void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { } internal void PaintInternal(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); } internal static bool PaintBackground(DataGridViewPaintParts paintParts) { return (paintParts & DataGridViewPaintParts.Background) != 0; } internal static bool PaintBorder(DataGridViewPaintParts paintParts) { return (paintParts & DataGridViewPaintParts.Border) != 0; } /// protected virtual void PaintBorder(Graphics graphics, Rectangle clipBounds, Rectangle bounds, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle) { if (graphics == null) { throw new ArgumentNullException("graphics"); } if (cellStyle == null) { throw new ArgumentNullException("cellStyle"); } if (this.DataGridView == null) { return; } // Using system colors for non-single grid colors for now int y1, y2; Pen penControlDark = null, penControlLightLight = null; Pen penBackColor = this.DataGridView.GetCachedPen(cellStyle.BackColor); Pen penGridColor = this.DataGridView.GridPen; GetContrastedPens(cellStyle.BackColor, ref penControlDark, ref penControlLightLight); int dividerThickness = this.owningColumn == null ? 0 : this.owningColumn.DividerWidth; if (dividerThickness != 0) { if (dividerThickness > bounds.Width) { dividerThickness = bounds.Width; } Color dividerWidthColor; switch (advancedBorderStyle.Right) { case DataGridViewAdvancedCellBorderStyle.Single: dividerWidthColor = this.DataGridView.GridPen.Color; break; case DataGridViewAdvancedCellBorderStyle.Inset: dividerWidthColor = SystemColors.ControlLightLight; break; default: /* ie DataGridViewAdvancedCellBorderStyle.Outset, DataGridViewAdvancedCellBorderStyle.OutsetPartial, DataGridViewAdvancedCellBorderStyle.None */ dividerWidthColor = SystemColors.ControlDark; break; } graphics.FillRectangle(this.DataGridView.GetCachedBrush(dividerWidthColor), this.DataGridView.RightToLeftInternal ? bounds.X : bounds.Right - dividerThickness, bounds.Y, dividerThickness, bounds.Height); if (this.DataGridView.RightToLeftInternal) { bounds.X += dividerThickness; } bounds.Width -= dividerThickness; if (bounds.Width <= 0) { return; } } dividerThickness = this.owningRow == null ? 0 : this.owningRow.DividerHeight; if (dividerThickness != 0) { if (dividerThickness > bounds.Height) { dividerThickness = bounds.Height; } Color dividerHeightColor; switch (advancedBorderStyle.Bottom) { case DataGridViewAdvancedCellBorderStyle.Single: dividerHeightColor = this.DataGridView.GridPen.Color; break; case DataGridViewAdvancedCellBorderStyle.Inset: dividerHeightColor = SystemColors.ControlLightLight; break; default: /* ie DataGridViewAdvancedCellBorderStyle.Outset, DataGridViewAdvancedCellBorderStyle.OutsetPartial, DataGridViewAdvancedCellBorderStyle.None */ dividerHeightColor = SystemColors.ControlDark; break; } graphics.FillRectangle(this.DataGridView.GetCachedBrush(dividerHeightColor), bounds.X, bounds.Bottom - dividerThickness, bounds.Width, dividerThickness); bounds.Height -= dividerThickness; if (bounds.Height <= 0) { return; } } if (advancedBorderStyle.All == DataGridViewAdvancedCellBorderStyle.None) { return; } switch (advancedBorderStyle.Left) { case DataGridViewAdvancedCellBorderStyle.Single: graphics.DrawLine(penGridColor, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Inset: graphics.DrawLine(penControlDark, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Outset: graphics.DrawLine(penControlLightLight, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: y1 = bounds.Y + 2; y2 = bounds.Bottom - 3; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.InsetDouble) { y1++; } else if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } graphics.DrawLine(penBackColor, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); graphics.DrawLine(penControlLightLight, bounds.X, y1, bounds.X, y2); break; case DataGridViewAdvancedCellBorderStyle.OutsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial) { y2++; } graphics.DrawLine(penControlDark, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); graphics.DrawLine(penControlLightLight, bounds.X + 1, y1, bounds.X + 1, y2); break; case DataGridViewAdvancedCellBorderStyle.InsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial) { y2++; } graphics.DrawLine(penControlLightLight, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); graphics.DrawLine(penControlDark, bounds.X + 1, y1, bounds.X + 1, y2); break; } switch (advancedBorderStyle.Right) { case DataGridViewAdvancedCellBorderStyle.Single: graphics.DrawLine(penGridColor, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Inset: graphics.DrawLine(penControlLightLight, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Outset: graphics.DrawLine(penControlDark, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: y1 = bounds.Y + 2; y2 = bounds.Bottom - 3; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.InsetDouble) { y1++; } else if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } graphics.DrawLine(penBackColor, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); graphics.DrawLine(penControlDark, bounds.Right - 1, y1, bounds.Right - 1, y2); break; case DataGridViewAdvancedCellBorderStyle.OutsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial) { y2++; } graphics.DrawLine(penControlDark, bounds.Right - 2, bounds.Y, bounds.Right - 2, bounds.Bottom - 1); graphics.DrawLine(penControlLightLight, bounds.Right - 1, y1, bounds.Right - 1, y2); break; case DataGridViewAdvancedCellBorderStyle.InsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.Inset) { y2++; } graphics.DrawLine(penControlLightLight, bounds.Right - 2, bounds.Y, bounds.Right - 2, bounds.Bottom - 1); graphics.DrawLine(penControlDark, bounds.Right - 1, y1, bounds.Right - 1, y2); break; } int x1, x2; switch (advancedBorderStyle.Top) { case DataGridViewAdvancedCellBorderStyle.Single: graphics.DrawLine(penGridColor, bounds.X, bounds.Y, bounds.Right - 1, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.Inset: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Inset || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Outset) { x2--; } graphics.DrawLine(penControlDark, x1, bounds.Y, x2, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.Outset: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Inset || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Outset) { x2--; } graphics.DrawLine(penControlLightLight, x1, bounds.Y, x2, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x1++; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } } if (advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x2--; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x2--; } } graphics.DrawLine(penBackColor, x1, bounds.Y, x2, bounds.Y); graphics.DrawLine(penControlLightLight, x1 + 1, bounds.Y, x2 - 1, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.OutsetDouble: x1 = bounds.X; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None) { x1++; } x2 = bounds.Right - 2; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.None) { x2++; } graphics.DrawLine(penControlDark, bounds.X, bounds.Y, bounds.Right - 1, bounds.Y); graphics.DrawLine(penControlLightLight, x1, bounds.Y + 1, x2, bounds.Y + 1); break; case DataGridViewAdvancedCellBorderStyle.InsetDouble: x1 = bounds.X; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None) { x1++; } x2 = bounds.Right - 2; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.None) { x2++; } graphics.DrawLine(penControlLightLight, bounds.X, bounds.Y, bounds.Right - 1, bounds.Y); graphics.DrawLine(penControlDark, x1, bounds.Y + 1, x2, bounds.Y + 1); break; } switch (advancedBorderStyle.Bottom) { case DataGridViewAdvancedCellBorderStyle.Single: graphics.DrawLine(penGridColor, bounds.X, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Inset: x2 = bounds.Right - 1; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x2--; } graphics.DrawLine(penControlLightLight, bounds.X, bounds.Bottom - 1, x2, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Outset: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetDouble) { x2--; } graphics.DrawLine(penControlDark, x1, bounds.Bottom - 1, x2, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x1++; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } } if (advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x2--; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x2--; } } graphics.DrawLine(penBackColor, x1, bounds.Bottom - 1, x2, bounds.Bottom - 1); graphics.DrawLine(penControlDark, x1 + 1, bounds.Bottom - 1, x2 - 1, bounds.Bottom - 1); break; } #if DGV_GDI // Using system colors for non-single grid colors for now int y1, y2; WindowsPen penControlDark = null, penControlLightLight = null; WindowsPen penBackColor = this.DataGridView.GetCachedWindowsPen(cellStyle.BackColor); WindowsPen penGridColor = this.DataGridView.GetCachedWindowsPen(this.DataGridView.GridColor); GetContrastedWindowsPens(cellStyle.BackColor, ref penControlDark, ref penControlLightLight); using (WindowsGraphics windowsGraphics = WindowsGraphics.FromGraphics(graphics)) { int dividerThickness = this.owningColumn == null ? 0 : this.owningColumn.DividerWidth; if (dividerThickness != 0) { if (dividerThickness > bounds.Width) { dividerThickness = bounds.Width; } Color dividerWidthColor; switch (advancedBorderStyle.Right) { case DataGridViewAdvancedCellBorderStyle.Single: dividerWidthColor = this.DataGridView.GridPen.Color; break; case DataGridViewAdvancedCellBorderStyle.Inset: dividerWidthColor = SystemColors.ControlLightLight; break; default: /* ie DataGridViewAdvancedCellBorderStyle.Outset, DataGridViewAdvancedCellBorderStyle.OutsetPartial, DataGridViewAdvancedCellBorderStyle.None */ dividerWidthColor = SystemColors.ControlDark; break; } windowsGraphics.FillRectangle(this.DataGridView.GetCachedWindowsBrush(dividerWidthColor), this.DataGridView.RightToLeftInternal ? bounds.X : bounds.Right - dividerThickness, bounds.Y, dividerThickness, bounds.Height); if (this.DataGridView.RightToLeftInternal) { bounds.X += dividerThickness; } bounds.Width -= dividerThickness; if (bounds.Width <= 0) { return; } } dividerThickness = this.owningRow == null ? 0 : this.owningRow.DividerHeight; if (dividerThickness != 0) { if (dividerThickness > bounds.Height) { dividerThickness = bounds.Height; } Color dividerHeightColor; switch (advancedBorderStyle.Bottom) { case DataGridViewAdvancedCellBorderStyle.Single: dividerHeightColor = this.DataGridView.GridPen.Color; break; case DataGridViewAdvancedCellBorderStyle.Inset: dividerHeightColor = SystemColors.ControlLightLight; break; default: /* ie DataGridViewAdvancedCellBorderStyle.Outset, DataGridViewAdvancedCellBorderStyle.OutsetPartial, DataGridViewAdvancedCellBorderStyle.None */ dividerHeightColor = SystemColors.ControlDark; break; } windowsGraphics.FillRectangle(this.DataGridView.GetCachedWindowsBrush(dividerHeightColor), bounds.X, bounds.Bottom - dividerThickness, bounds.Width, dividerThickness); bounds.Height -= dividerThickness; if (bounds.Height <= 0) { return; } } if (advancedBorderStyle.All == DataGridViewAdvancedCellBorderStyle.None) { return; } switch (advancedBorderStyle.Left) { case DataGridViewAdvancedCellBorderStyle.Single: windowsGraphics.DrawLine(penGridColor, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Inset: windowsGraphics.DrawLine(penControlDark, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Outset: windowsGraphics.DrawLine(penControlLightLight, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: y1 = bounds.Y + 2; y2 = bounds.Bottom - 3; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.InsetDouble) { y1++; } else if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } windowsGraphics.DrawLine(penBackColor, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); windowsGraphics.DrawLine(penControlLightLight, bounds.X, y1, bounds.X, y2); break; case DataGridViewAdvancedCellBorderStyle.OutsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial) { y2++; } windowsGraphics.DrawLine(penControlDark, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); windowsGraphics.DrawLine(penControlLightLight, bounds.X + 1, y1, bounds.X + 1, y2); break; case DataGridViewAdvancedCellBorderStyle.InsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial) { y2++; } windowsGraphics.DrawLine(penControlLightLight, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); windowsGraphics.DrawLine(penControlDark, bounds.X + 1, y1, bounds.X + 1, y2); break; } switch (advancedBorderStyle.Right) { case DataGridViewAdvancedCellBorderStyle.Single: windowsGraphics.DrawLine(penGridColor, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Inset: windowsGraphics.DrawLine(penControlLightLight, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Outset: windowsGraphics.DrawLine(penControlDark, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: y1 = bounds.Y + 2; y2 = bounds.Bottom - 3; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.InsetDouble) { y1++; } else if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } windowsGraphics.DrawLine(penBackColor, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); windowsGraphics.DrawLine(penControlDark, bounds.Right - 1, y1, bounds.Right - 1, y2); break; case DataGridViewAdvancedCellBorderStyle.OutsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial) { y2++; } windowsGraphics.DrawLine(penControlDark, bounds.Right - 2, bounds.Y, bounds.Right - 2, bounds.Bottom - 1); windowsGraphics.DrawLine(penControlLightLight, bounds.Right - 1, y1, bounds.Right - 1, y2); break; case DataGridViewAdvancedCellBorderStyle.InsetDouble: y1 = bounds.Y + 1; y2 = bounds.Bottom - 1; if (advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Top == DataGridViewAdvancedCellBorderStyle.None) { y1--; } if (advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Bottom == DataGridViewAdvancedCellBorderStyle.Inset) { y2++; } windowsGraphics.DrawLine(penControlLightLight, bounds.Right - 2, bounds.Y, bounds.Right - 2, bounds.Bottom - 1); windowsGraphics.DrawLine(penControlDark, bounds.Right - 1, y1, bounds.Right - 1, y2); break; } int x1, x2; switch (advancedBorderStyle.Top) { case DataGridViewAdvancedCellBorderStyle.Single: windowsGraphics.DrawLine(penGridColor, bounds.X, bounds.Y, bounds.Right - 1, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.Inset: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Inset || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Outset) { x2--; } windowsGraphics.DrawLine(penControlDark, x1, bounds.Y, x2, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.Outset: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Inset || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.Outset) { x2--; } windowsGraphics.DrawLine(penControlLightLight, x1, bounds.Y, x2, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x1++; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } } if (advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x2--; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x2--; } } windowsGraphics.DrawLine(penBackColor, x1, bounds.Y, x2, bounds.Y); windowsGraphics.DrawLine(penControlLightLight, x1 + 1, bounds.Y, x2 - 1, bounds.Y); break; case DataGridViewAdvancedCellBorderStyle.OutsetDouble: x1 = bounds.X; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None) { x1++; } x2 = bounds.Right - 2; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.None) { x2++; } windowsGraphics.DrawLine(penControlDark, bounds.X, bounds.Y, bounds.Right - 1, bounds.Y); windowsGraphics.DrawLine(penControlLightLight, x1, bounds.Y + 1, x2, bounds.Y + 1); break; case DataGridViewAdvancedCellBorderStyle.InsetDouble: x1 = bounds.X; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None) { x1++; } x2 = bounds.Right - 2; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetPartial || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.None) { x2++; } windowsGraphics.DrawLine(penControlLightLight, bounds.X, bounds.Y, bounds.Right - 1, bounds.Y); windowsGraphics.DrawLine(penControlDark, x1, bounds.Y + 1, x2, bounds.Y + 1); break; } switch (advancedBorderStyle.Bottom) { case DataGridViewAdvancedCellBorderStyle.Single: windowsGraphics.DrawLine(penGridColor, bounds.X, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Inset: x2 = bounds.Right - 1; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x2--; } windowsGraphics.DrawLine(penControlLightLight, bounds.X, bounds.Bottom - 1, x2, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.Outset: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetDouble) { x2--; } windowsGraphics.DrawLine(penControlDark, x1, bounds.Bottom - 1, x2, bounds.Bottom - 1); break; case DataGridViewAdvancedCellBorderStyle.OutsetPartial: x1 = bounds.X; x2 = bounds.Right - 1; if (advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Left != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x1++; if (advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Left == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x1++; } } if (advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.None /* && advancedBorderStyle.Right != DataGridViewAdvancedCellBorderStyle.OutsetPartial*/) { x2--; if (advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.OutsetDouble || advancedBorderStyle.Right == DataGridViewAdvancedCellBorderStyle.InsetDouble) { x2--; } } windowsGraphics.DrawLine(penBackColor, x1, bounds.Bottom - 1, x2, bounds.Bottom - 1); windowsGraphics.DrawLine(penControlDark, x1 + 1, bounds.Bottom - 1, x2 - 1, bounds.Bottom - 1); break; } } #endif // DGV_GDI } internal static bool PaintContentBackground(DataGridViewPaintParts paintParts) { return (paintParts & DataGridViewPaintParts.ContentBackground) != 0; } internal static bool PaintContentForeground(DataGridViewPaintParts paintParts) { return (paintParts & DataGridViewPaintParts.ContentForeground) != 0; } /// protected virtual void PaintErrorIcon(Graphics graphics, Rectangle clipBounds, Rectangle cellValueBounds, string errorText) { if (!string.IsNullOrEmpty(errorText) && cellValueBounds.Width >= DATAGRIDVIEWCELL_iconMarginWidth*2+DATAGRIDVIEWCELL_iconsWidth && cellValueBounds.Height >= DATAGRIDVIEWCELL_iconMarginHeight*2+DATAGRIDVIEWCELL_iconsHeight) { PaintErrorIcon(graphics, ComputeErrorIconBounds(cellValueBounds)); } } [SuppressMessage("Microsoft.Reliability", "CA2002:DoNotLockOnObjectsWithWeakIdentity")] private static void PaintErrorIcon(Graphics graphics, Rectangle iconBounds) { Bitmap bmp = DataGridViewCell.ErrorBitmap; if (bmp != null) { lock (bmp) { graphics.DrawImage(bmp, iconBounds, 0, 0, DATAGRIDVIEWCELL_iconsWidth, DATAGRIDVIEWCELL_iconsHeight, GraphicsUnit.Pixel); } } } internal void PaintErrorIcon(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Rectangle cellBounds, Rectangle cellValueBounds, string errorText) { if (!string.IsNullOrEmpty(errorText) && cellValueBounds.Width >= DATAGRIDVIEWCELL_iconMarginWidth * 2 + DATAGRIDVIEWCELL_iconsWidth && cellValueBounds.Height >= DATAGRIDVIEWCELL_iconMarginHeight * 2 + DATAGRIDVIEWCELL_iconsHeight) { Rectangle iconBounds = GetErrorIconBounds(graphics, cellStyle, rowIndex); if (iconBounds.Width >= DATAGRIDVIEWCELL_iconMarginWidth && iconBounds.Height >= DATAGRIDVIEWCELL_iconsHeight) { iconBounds.X += cellBounds.X; iconBounds.Y += cellBounds.Y; PaintErrorIcon(graphics, iconBounds); } } } internal static bool PaintErrorIcon(DataGridViewPaintParts paintParts) { return (paintParts & DataGridViewPaintParts.ErrorIcon) != 0; } internal static bool PaintFocus(DataGridViewPaintParts paintParts) { return (paintParts & DataGridViewPaintParts.Focus) != 0; } static internal void PaintPadding(Graphics graphics, Rectangle bounds, DataGridViewCellStyle cellStyle, Brush br, bool rightToLeft) { Rectangle rectPadding; if (rightToLeft) { rectPadding = new Rectangle(bounds.X, bounds.Y, cellStyle.Padding.Right, bounds.Height); graphics.FillRectangle(br, rectPadding); rectPadding.X = bounds.Right - cellStyle.Padding.Left; rectPadding.Width = cellStyle.Padding.Left; graphics.FillRectangle(br, rectPadding); rectPadding.X = bounds.Left + cellStyle.Padding.Right; } else { rectPadding = new Rectangle(bounds.X, bounds.Y, cellStyle.Padding.Left, bounds.Height); graphics.FillRectangle(br, rectPadding); rectPadding.X = bounds.Right - cellStyle.Padding.Right; rectPadding.Width = cellStyle.Padding.Right; graphics.FillRectangle(br, rectPadding); rectPadding.X = bounds.Left + cellStyle.Padding.Left; } rectPadding.Y = bounds.Y; rectPadding.Width = bounds.Width - cellStyle.Padding.Horizontal; rectPadding.Height = cellStyle.Padding.Top; graphics.FillRectangle(br, rectPadding); rectPadding.Y = bounds.Bottom - cellStyle.Padding.Bottom; rectPadding.Height = cellStyle.Padding.Bottom; graphics.FillRectangle(br, rectPadding); } internal static bool PaintSelectionBackground(DataGridViewPaintParts paintParts) { return (paintParts & DataGridViewPaintParts.SelectionBackground) != 0; } internal void PaintWork(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { Debug.Assert(this.DataGridView != null); DataGridView dataGridView = this.DataGridView; int columnIndex = this.ColumnIndex; object formattedValue, value = GetValue(rowIndex); string errorText = GetErrorText(rowIndex); if (columnIndex > -1 && rowIndex > -1) { formattedValue = GetEditedFormattedValue(value, rowIndex, ref cellStyle, DataGridViewDataErrorContexts.Formatting | DataGridViewDataErrorContexts.Display); } else { // No formatting applied on header cells. formattedValue = value; } DataGridViewCellPaintingEventArgs dgvcpe = dataGridView.CellPaintingEventArgs; dgvcpe.SetProperties(graphics, clipBounds, cellBounds, rowIndex, columnIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); dataGridView.OnCellPainting(dgvcpe); if (dgvcpe.Handled) { return; } Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); } /// public virtual object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) { return ParseFormattedValueInternal(this.ValueType, formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter); } internal object ParseFormattedValueInternal(Type valueType, object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) { if (cellStyle == null) { throw new ArgumentNullException("cellStyle"); } if (this.FormattedValueType == null) { throw new FormatException(SR.GetString(SR.DataGridViewCell_FormattedValueTypeNull)); } if (valueType == null) { throw new FormatException(SR.GetString(SR.DataGridViewCell_ValueTypeNull)); } if (formattedValue == null || !this.FormattedValueType.IsAssignableFrom(formattedValue.GetType())) { throw new ArgumentException(SR.GetString(SR.DataGridViewCell_FormattedValueHasWrongType), "formattedValue"); } return Formatter.ParseObject(formattedValue, valueType, this.FormattedValueType, valueTypeConverter == null ? this.ValueTypeConverter : valueTypeConverter /*sourceConverter*/, formattedValueTypeConverter == null ? this.FormattedValueTypeConverter : formattedValueTypeConverter /*targetConverter*/, cellStyle.FormatProvider, cellStyle.NullValue, cellStyle.IsDataSourceNullValueDefault ? Formatter.GetDefaultDataSourceNullValue(valueType) : cellStyle.DataSourceNullValue); } /// [ EditorBrowsable(EditorBrowsableState.Advanced) ] public virtual void PositionEditingControl( bool setLocation, bool setSize, Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) { Rectangle editingControlBounds = PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); if (setLocation) { this.DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); } if (setSize) { this.DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); } } /// [ EditorBrowsable(EditorBrowsableState.Advanced), SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters") // singleVerticalBorderAdded/singleHorizontalBorderAdded names are OK ] // Positions the editing panel and returns the normal bounds of the editing control, within the editing panel. public virtual Rectangle PositionEditingPanel(Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) { if (this.DataGridView == null) { throw new InvalidOperationException(); } DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder = new DataGridViewAdvancedBorderStyle(), dgvabsEffective; dgvabsEffective = AdjustCellBorderStyle(this.DataGridView.AdvancedCellBorderStyle, dataGridViewAdvancedBorderStylePlaceholder, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); Rectangle borderAndPaddingWidths = BorderWidths(dgvabsEffective); borderAndPaddingWidths.X += cellStyle.Padding.Left; borderAndPaddingWidths.Y += cellStyle.Padding.Top; borderAndPaddingWidths.Width += cellStyle.Padding.Right; borderAndPaddingWidths.Height += cellStyle.Padding.Bottom; int xEditingPanel, wEditingPanel = cellBounds.Width; int xEditingControl, wEditingControl; int yEditingPanel, hEditingPanel = cellBounds.Height; int yEditingControl, hEditingControl; if (cellClip.X - cellBounds.X >= borderAndPaddingWidths.X) { xEditingPanel = cellClip.X; wEditingPanel -= cellClip.X - cellBounds.X; } else { xEditingPanel = cellBounds.X + borderAndPaddingWidths.X; wEditingPanel -= borderAndPaddingWidths.X; } if (cellClip.Right <= cellBounds.Right - borderAndPaddingWidths.Width) { wEditingPanel -= cellBounds.Right - cellClip.Right; } else { wEditingPanel -= borderAndPaddingWidths.Width; } xEditingControl = cellBounds.X - cellClip.X; wEditingControl = cellBounds.Width - borderAndPaddingWidths.X - borderAndPaddingWidths.Width; if (cellClip.Y - cellBounds.Y >= borderAndPaddingWidths.Y) { yEditingPanel = cellClip.Y; hEditingPanel -= cellClip.Y - cellBounds.Y; } else { yEditingPanel = cellBounds.Y + borderAndPaddingWidths.Y; hEditingPanel -= borderAndPaddingWidths.Y; } if (cellClip.Bottom <= cellBounds.Bottom - borderAndPaddingWidths.Height) { hEditingPanel -= cellBounds.Bottom - cellClip.Bottom; } else { hEditingPanel -= borderAndPaddingWidths.Height; } yEditingControl = cellBounds.Y - cellClip.Y; hEditingControl = cellBounds.Height - borderAndPaddingWidths.Y - borderAndPaddingWidths.Height; this.DataGridView.EditingPanel.Location = new Point(xEditingPanel, yEditingPanel); this.DataGridView.EditingPanel.Size = new Size(wEditingPanel, hEditingPanel); /* Code was added for VSWhidbey 274393 and removed for 461211. if (this.DataGridView.RightToLeftInternal) { xEditingControl = wEditingPanel - xEditingControl - wEditingControl; } */ return new Rectangle(xEditingControl, yEditingControl, wEditingControl, hEditingControl); } /// protected virtual bool SetValue(int rowIndex, object value) { object originalValue = null; DataGridView dataGridView = this.DataGridView; if (dataGridView != null && !dataGridView.InSortOperation) { originalValue = GetValue(rowIndex); } if (dataGridView != null && this.OwningColumn != null && this.OwningColumn.IsDataBound) { DataGridView.DataGridViewDataConnection dataConnection = dataGridView.DataConnection; if (dataConnection == null) { return false; } else if (dataConnection.CurrencyManager.Count <= rowIndex) { if (value != null || this.Properties.ContainsObject(PropCellValue)) { this.Properties.SetObject(PropCellValue, value); } } else { if (dataConnection.PushValue(this.OwningColumn.BoundColumnIndex, this.ColumnIndex, rowIndex, value)) { if (this.DataGridView == null || this.OwningRow == null || this.OwningRow.DataGridView == null) { // As a result of pushing the value in the back end, the data grid view row and/or data grid view cell // became disconnected from the DataGridView. // Return true because the operation succeded. // However, because the row which was edited became disconnected from the DataGridView, // do not mark the current row in the data grid view as being dirty. // And because the data grid view cell which was edited became disconnected from the data grid view // do not fire CellValueChanged event. // vsw 543015. return true; } if (this.OwningRow.Index == this.DataGridView.CurrentCellAddress.Y) { // The user programatically changed a value in the current row. // The DataGridView already opened a transaction for the current row. // All is left to do is to mark the current row in the DataGridView as being dirty. this.DataGridView.IsCurrentRowDirtyInternal = true; } } else { return false; } } } else if (dataGridView == null || !dataGridView.VirtualMode || rowIndex == -1 || this.ColumnIndex == -1) { if (value != null || this.Properties.ContainsObject(PropCellValue)) { this.Properties.SetObject(PropCellValue, value); } } else { Debug.Assert(rowIndex >= 0); Debug.Assert(this.ColumnIndex >= 0); dataGridView.OnCellValuePushed(this.ColumnIndex, rowIndex, value); } if (dataGridView != null && !dataGridView.InSortOperation && ((originalValue == null && value != null) || (originalValue != null && value == null) || (originalValue != null && !value.Equals(originalValue)))) { RaiseCellValueChanged(new DataGridViewCellEventArgs(this.ColumnIndex, rowIndex)); } return true; } internal bool SetValueInternal(int rowIndex, object value) { return SetValue(rowIndex, value); } internal static bool TextFitsInBounds(Graphics graphics, string text, Font font, Size maxBounds, TextFormatFlags flags) { bool widthTruncated; int requiredHeight = DataGridViewCell.MeasureTextHeight(graphics, text, font, maxBounds.Width, flags, out widthTruncated); return requiredHeight <= maxBounds.Height && !widthTruncated; } /// /// /// /// Gets the row Index and column Index of the cell. /// /// public override string ToString() { return "DataGridViewCell { ColumnIndex=" + this.ColumnIndex.ToString(CultureInfo.CurrentCulture) + ", RowIndex=" + this.RowIndex.ToString(CultureInfo.CurrentCulture) + " }"; } private static string TruncateToolTipText(string toolTipText) { if (toolTipText.Length > DATAGRIDVIEWCELL_maxToolTipLength) { StringBuilder sb = new StringBuilder(toolTipText.Substring(0, DATAGRIDVIEWCELL_maxToolTipCutOff), DATAGRIDVIEWCELL_maxToolTipCutOff + DATAGRIDVIEWCELL_toolTipEllipsisLength); sb.Append(DATAGRIDVIEWCELL_toolTipEllipsis); return sb.ToString(); } return toolTipText; } private void UpdateCurrentMouseLocation(DataGridViewCellMouseEventArgs e) { if (GetErrorIconBounds(e.RowIndex).Contains(e.X, e.Y)) { this.CurrentMouseLocation = DATAGRIDVIEWCELL_flagErrorArea; } else { this.CurrentMouseLocation = DATAGRIDVIEWCELL_flagDataArea; } } /// [ System.Runtime.InteropServices.ComVisible(true) ] protected class DataGridViewCellAccessibleObject : AccessibleObject { DataGridViewCell owner; /// public DataGridViewCellAccessibleObject() { } /// public DataGridViewCellAccessibleObject(DataGridViewCell owner) { this.owner = owner; } /// public override Rectangle Bounds { get { return this.GetAccessibleObjectBounds(GetAccessibleObjectParent()); } } /// public override string DefaultAction { get { if (this.Owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if (!this.Owner.ReadOnly) { return SR.GetString(SR.DataGridView_AccCellDefaultAction); } else { return String.Empty; } } } /// public override string Help { get { return this.owner.GetType().Name + "(" + owner.GetType().BaseType.Name + ")"; } } /// public override string Name { get { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if (this.owner.OwningColumn != null) { return SR.GetString(SR.DataGridView_AccDataGridViewCellName, this.owner.OwningColumn.HeaderText, this.owner.OwningRow.Index); } else { return String.Empty; } } } /// public DataGridViewCell Owner { get { return this.owner; } set { if (this.owner != null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerAlreadySet)); } this.owner = value; } } /// public override AccessibleObject Parent { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { return this.ParentPrivate; } } private AccessibleObject ParentPrivate { get { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if (this.owner.OwningRow == null) { return null; } else { return this.owner.OwningRow.AccessibilityObject; } } } /// public override AccessibleRole Role { get { return AccessibleRole.Cell; } } /// public override AccessibleStates State { get { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } AccessibleStates state = AccessibleStates.Selectable | AccessibleStates.Focusable; if (this.owner == this.owner.DataGridView.CurrentCell) { state |= AccessibleStates.Focused; } if (this.owner.Selected) { state |= AccessibleStates.Selected; } Rectangle cellBounds; if (this.owner.OwningColumn != null && this.owner.OwningRow != null) { cellBounds = this.owner.DataGridView.GetCellDisplayRectangle(this.owner.OwningColumn.Index, this.owner.OwningRow.Index, false /*cutOverflow*/); } else if (this.owner.OwningRow != null) { cellBounds = this.owner.DataGridView.GetCellDisplayRectangle(-1, this.owner.OwningRow.Index, false /*cutOverflow*/); } else if (this.owner.OwningColumn != null) { cellBounds = this.owner.DataGridView.GetCellDisplayRectangle(this.owner.OwningColumn.Index, -1, false /*cutOverflow*/); } else { cellBounds = this.owner.DataGridView.GetCellDisplayRectangle(-1, -1, false /*cutOverflow*/); } if (!cellBounds.IntersectsWith(this.owner.DataGridView.ClientRectangle)) { state |= AccessibleStates.Offscreen; } return state; } } /// public override string Value { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } object formattedValue = this.owner.FormattedValue; string formattedValueAsString = formattedValue as string; if (formattedValue == null || (formattedValueAsString != null && String.IsNullOrEmpty(formattedValueAsString))) { return SR.GetString(SR.DataGridView_AccNullValue); } else if (formattedValueAsString != null) { return formattedValueAsString; } else if (this.owner.OwningColumn != null) { TypeConverter converter = this.owner.FormattedValueTypeConverter; if (converter != null && converter.CanConvertTo(typeof(string))) { return converter.ConvertToString(formattedValue); } else { return formattedValue.ToString(); } } else { return String.Empty; } } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] set { if (this.owner is DataGridViewHeaderCell) { return; } if (this.owner.ReadOnly) { return; } if (this.owner.OwningRow == null) { return; } if (this.owner.DataGridView.IsCurrentCellInEditMode) { // EndEdit before setting the accessible object value. // This way the value being edited is validated. this.owner.DataGridView.EndEdit(); } DataGridViewCellStyle dataGridViewCellStyle = this.owner.InheritedStyle; // Format string "True" to boolean True. object formattedValue = this.owner.GetFormattedValue(value, this.owner.OwningRow.Index, ref dataGridViewCellStyle, null /*formattedValueTypeConverter*/ , null /*valueTypeConverter*/, DataGridViewDataErrorContexts.Formatting); // Parse the formatted value and push it into the back end. this.owner.Value = owner.ParseFormattedValue(formattedValue, dataGridViewCellStyle, null /*formattedValueTypeConverter*/, null /*valueTypeConverter*/); } } /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void DoDefaultAction() { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } DataGridViewCell dataGridViewCell = (DataGridViewCell)this.Owner; DataGridView dataGridView = dataGridViewCell.DataGridView; if (dataGridViewCell is DataGridViewHeaderCell) { return; } if (dataGridView != null && dataGridViewCell.RowIndex == -1) { throw new InvalidOperationException(SR.GetString(SR.DataGridView_InvalidOperationOnSharedCell)); } Select(AccessibleSelection.TakeFocus | AccessibleSelection.TakeSelection); Debug.Assert(dataGridView.CurrentCell == dataGridViewCell, "the result of selecting the cell should have made this cell the current cell"); if (dataGridViewCell.ReadOnly) { // don't edit if the cell is read only return; } if (dataGridViewCell.EditType != null) { if (dataGridView.InBeginEdit || dataGridView.InEndEdit) { // don't enter or exit editing mode if the control // is in the middle of doing that already. return; } if (dataGridView.IsCurrentCellInEditMode) { // stop editing dataGridView.EndEdit(); } else if (dataGridView.EditMode != DataGridViewEditMode.EditProgrammatically) { // start editing dataGridView.BeginEdit(true /*selectAll*/); } } } internal Rectangle GetAccessibleObjectBounds(AccessibleObject parentAccObject) { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if (this.owner.OwningColumn == null) { return Rectangle.Empty; } // use the accessibility bounds from the parent row acc obj Rectangle rowRect = parentAccObject.Bounds; Rectangle columnRect; int firstVisibleColumnIndex = this.owner.DataGridView.Columns.ColumnIndexToActualDisplayIndex(this.owner.DataGridView.FirstDisplayedScrollingColumnIndex, DataGridViewElementStates.Visible); int visibleColumnIndex = this.owner.DataGridView.Columns.ColumnIndexToActualDisplayIndex(this.owner.ColumnIndex, DataGridViewElementStates.Visible); bool rowHeadersVisible = this.owner.DataGridView.RowHeadersVisible; if (visibleColumnIndex < firstVisibleColumnIndex) { // Get the bounds for the cell to the RIGHT columnRect = parentAccObject.GetChild(visibleColumnIndex + 1 // + 1 for the next cell to the RIGHT + (rowHeadersVisible ? 1 : 0)).Bounds; // + 1 but only if the row headers are visible // From the bounds of the cell to the RIGHT decrement the width of the owning column if (this.Owner.DataGridView.RightToLeft == RightToLeft.No) { columnRect.X -= this.owner.OwningColumn.Width; } else { columnRect.X = columnRect.Right; } columnRect.Width = this.owner.OwningColumn.Width; } else if (visibleColumnIndex == firstVisibleColumnIndex) { columnRect = this.owner.DataGridView.GetColumnDisplayRectangle(this.owner.ColumnIndex, false /*cutOverflow*/); int negOffset = this.owner.DataGridView.FirstDisplayedScrollingColumnHiddenWidth; if (negOffset != 0) { if (this.owner.DataGridView.RightToLeft == RightToLeft.No) { columnRect.X -= negOffset; } columnRect.Width += negOffset; } columnRect = this.owner.DataGridView.RectangleToScreen(columnRect); } else { // Get the bounds for the cell to the LEFT columnRect = parentAccObject.GetChild(visibleColumnIndex - 1 // -1 because we want the previous cell to the LEFT + (rowHeadersVisible ? 1 : 0)).Bounds; // +1 but only if the row headers are visible // From the bounds of the cell to the LEFT increment the width of the owning column if (this.owner.DataGridView.RightToLeft == RightToLeft.No) { columnRect.X = columnRect.Right; } else { columnRect.X -= this.owner.OwningColumn.Width; } columnRect.Width = this.owner.OwningColumn.Width; } rowRect.X = columnRect.X; rowRect.Width = columnRect.Width; return rowRect; } private AccessibleObject GetAccessibleObjectParent() { // If this is one of our types, use the shortcut provided by ParentPrivate property. // Otherwise, use the Parent property. if (this.owner is DataGridViewButtonCell || this.owner is DataGridViewCheckBoxCell || this.owner is DataGridViewComboBoxCell || this.owner is DataGridViewImageCell || this.owner is DataGridViewLinkCell || this.owner is DataGridViewTextBoxCell) { return this.ParentPrivate; } else { return this.Parent; } } /// public override AccessibleObject GetChild(int index) { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if (this.owner.DataGridView.EditingControl != null && this.owner.DataGridView.IsCurrentCellInEditMode && this.owner.DataGridView.CurrentCell == this.owner && index == 0) { return this.owner.DataGridView.EditingControl.AccessibilityObject; } else { return null; } } /// public override int GetChildCount() { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if (this.owner.DataGridView.EditingControl != null && this.owner.DataGridView.IsCurrentCellInEditMode && this.owner.DataGridView.CurrentCell == this.owner) { return 1; } else { return 0; } } /// public override AccessibleObject GetFocused() { return null; } /// public override AccessibleObject GetSelected() { return null; } /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override AccessibleObject Navigate(AccessibleNavigation navigationDirection) { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if (this.owner.OwningColumn == null || this.owner.OwningRow == null) { return null; } switch (navigationDirection) { case AccessibleNavigation.Right: if (this.owner.DataGridView.RightToLeft == RightToLeft.No) { return NavigateForward(true /*wrapAround*/); } else { return NavigateBackward(true /*wrapAround*/); } case AccessibleNavigation.Next: return NavigateForward(false /*wrapAround*/); case AccessibleNavigation.Left: if (this.owner.DataGridView.RightToLeft == RightToLeft.No) { return NavigateBackward(true /*wrapAround*/); } else { return NavigateForward(true /*wrapAround*/); } case AccessibleNavigation.Previous: return NavigateBackward(false /*wrapAround*/); case AccessibleNavigation.Up: if (this.owner.OwningRow.Index == this.owner.DataGridView.Rows.GetFirstRow(DataGridViewElementStates.Visible)) { if (this.owner.DataGridView.ColumnHeadersVisible) { // Return the column header accessible object. return this.owner.OwningColumn.HeaderCell.AccessibilityObject; } else { return null; } } else { int previousVisibleRow = this.owner.DataGridView.Rows.GetPreviousRow(this.owner.OwningRow.Index, DataGridViewElementStates.Visible); return this.owner.DataGridView.Rows[previousVisibleRow].Cells[this.owner.OwningColumn.Index].AccessibilityObject; } case AccessibleNavigation.Down: if (this.owner.OwningRow.Index == this.owner.DataGridView.Rows.GetLastRow(DataGridViewElementStates.Visible)) { return null; } else { int nextVisibleRow = this.owner.DataGridView.Rows.GetNextRow(this.owner.OwningRow.Index, DataGridViewElementStates.Visible); return this.owner.DataGridView.Rows[nextVisibleRow].Cells[this.owner.OwningColumn.Index].AccessibilityObject; } default: return null; } } private AccessibleObject NavigateBackward(bool wrapAround) { if (this.owner.OwningColumn == this.owner.DataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible)) { if (wrapAround) { // Return the last accessible object in the previous row AccessibleObject previousRow = this.Owner.OwningRow.AccessibilityObject.Navigate(AccessibleNavigation.Previous); if (previousRow != null && previousRow.GetChildCount() > 0) { return previousRow.GetChild(previousRow.GetChildCount() - 1); } else { return null; } } else { // return the row header cell if the row headers are visible. if (this.owner.DataGridView.RowHeadersVisible) { return this.owner.OwningRow.AccessibilityObject.GetChild(0); } else { return null; } } } else { int previousVisibleColumnIndex = this.owner.DataGridView.Columns.GetPreviousColumn(this.owner.OwningColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None).Index; return this.owner.OwningRow.Cells[previousVisibleColumnIndex].AccessibilityObject; } } private AccessibleObject NavigateForward(bool wrapAround) { if (this.owner.OwningColumn == this.owner.DataGridView.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None)) { if (wrapAround) { // Return the first cell in the next visible row. // AccessibleObject nextRow = this.Owner.OwningRow.AccessibilityObject.Navigate(AccessibleNavigation.Next); if (nextRow != null && nextRow.GetChildCount() > 0) { if (this.Owner.DataGridView.RowHeadersVisible) { return nextRow.GetChild(1); } else { return nextRow.GetChild(0); } } else { return null; } } else { return null; } } else { int nextVisibleColumnIndex = this.owner.DataGridView.Columns.GetNextColumn(this.owner.OwningColumn, DataGridViewElementStates.Visible, DataGridViewElementStates.None).Index; return this.owner.OwningRow.Cells[nextVisibleColumnIndex].AccessibilityObject; } } /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void Select(AccessibleSelection flags) { if (this.owner == null) { throw new InvalidOperationException(SR.GetString(SR.DataGridViewCellAccessibleObject_OwnerNotSet)); } if ((flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) { this.owner.DataGridView.FocusInternal(); } if ((flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) { this.owner.Selected = true; this.owner.DataGridView.CurrentCell = this.owner; // Do not change old selection } if ((flags & AccessibleSelection.AddSelection) == AccessibleSelection.AddSelection) { // it seems that in any circumstances a cell can become selected this.owner.Selected = true; } if ((flags & AccessibleSelection.RemoveSelection) == AccessibleSelection.RemoveSelection && (flags & (AccessibleSelection.AddSelection | AccessibleSelection.TakeSelection)) == 0) { this.owner.Selected = false; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK