Click here to Skip to main content
15,894,410 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hi all

how to create the usercontrol(textbox + button) and place inside the datagridview.

1) when i click edit it is enable (usercontrol).
2) when i click button open lookup.
3) select a record and place the particular cell inside the datagridview.

let me know

Thanks in advance..........
Posted

Custom data grid view controls must implement IDataGridViewEditingControl, and then you need a custom DataGridViewCell class which uses it, and a DataGridViewColumn subclass which uses that cell type. See here (tutorial on MSDN)[^].
 
Share this answer
 
Comments
U@007 3-Aug-12 7:48am    
thank u bob this is also very useful.

in my side take 5!.
finally i done with reference of
http://www.softwaremasons.com/ChristysBlog/tabid/65/EntryId/19/Writing-a-Popup-Textbox-UserControl-for-a-DataGridView-in-Windows-Forms-ndash-Part-1.aspx[^]
http://www.softwaremasons.com/ChristysBlog/tabid/65/EntryId/22/Writing-a-Popup-Textbox-UserControl-for-a-DataGridView-in-Windows-Forms-ndash-Part-2.aspx[^]

//usercontrol design mode take textbox and button

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Test_Win
{
    public partial class DataGridViewButtonTextboxColumn : UserControl, IDataGridViewEditingControl
    {

        // The grid that owns this editing control
        private DataGridView dataGridView;
        // Stores whether the editing control's value has changed or not
        private bool valueChanged;
        // Stores the row index in which the editing control resides
        private int rowIndex;
        private int _maxInputLength = 255;

        Lookup objfrm = null;

        public DataGridViewButtonTextboxColumn()
        {
            this.TabStop = false;
            InitializeComponent();
            this.txtEnter.MaxLength = _maxInputLength;
        }

        private void BtnOk_Click(object sender, EventArgs e)
        {
            objfrm = new Lookup();
            objfrm.ShowDialog();
            if (objfrm.EmpNumber != null)
                txtEnter.Text = objfrm.EmpNumber;
        }

        private void txtEnter_TextChanged(object sender, EventArgs e)
        {
            this.OnTextChanged(e);
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            this.txtEnter.Focus();
        }

        /// <summary>
        /// Text inside text box of the EllipsesTextbox control
        /// </summary>
        [Category("Appearance"), Description("Text Value"), DisplayName("TextValue")]
        public string TextValue
        {
            get
            {
                return this.txtEnter.Text;
            }
            set
            {
                if (value.Length <= MaxLength)
                {
                    this.txtEnter.Text = value;
                }
            }
        }

        /// <summary>
        /// Maximum length in the text box of the EllipsesTextbox control
        /// </summary>
        [Category("Behavior"), Description("Max Input Length"), DefaultValue(255), DisplayName("MaxLength")]
        public int MaxLength
        {
            get
            {
                return _maxInputLength;
            }
            set
            {
                if (value > 0)
                {
                    _maxInputLength = value;
                    this.txtEnter.MaxLength = _maxInputLength;
                }
            }
        }

        #region Properties

        #region Properties for implementation of IDataGridViewEditingControl interface

        /// <summary>
        /// Property which caches the grid that uses this editing control
        /// </summary>
        public virtual DataGridView EditingControlDataGridView
        {
            get
            {
                return this.dataGridView;
            }
            set
            {
                this.dataGridView = value;
            }
        }

        /// <summary>
        /// Property which represents the current formatted value of the editing control
        /// </summary>
        public virtual object EditingControlFormattedValue
        {
            get
            {
                return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
            }
            set
            {
                this.TextValue = (string)value;
            }
        }

        /// <summary>
        /// Property which represents the row in which the editing control resides
        /// </summary>
        public virtual int EditingControlRowIndex
        {
            get
            {
                return this.rowIndex;
            }
            set
            {
                this.rowIndex = value;
            }
        }

        /// <summary>
        /// Property which indicates whether the value of the editing control has changed or not
        /// </summary>
        public virtual bool EditingControlValueChanged
        {
            get
            {
                return this.valueChanged;
            }
            set
            {
                this.valueChanged = value;
            }
        }

        /// <summary>
        /// Property which determines which cursor must be used for the editing panel,
        /// i.e. the parent of the editing control.
        /// </summary>
        public virtual Cursor EditingPanelCursor
        {
            get
            {
                return Cursors.Default;
            }
        }

        /// <summary>
        /// Property which indicates whether the editing control needs to be repositioned
        /// when its value changes.
        /// </summary>
        public virtual bool RepositionEditingControlOnValueChange
        {
            get
            {
                return false;
            }
        }
        #endregion
        #endregion

        #region Methods

        #region Methods for implementation of IDataGridViewEditingControl interface

        /// <summary>
        /// Method called by the grid before the editing control is shown so it can adapt to the
        /// provided cell style.
        /// </summary>
        public virtual void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            this.Font = dataGridViewCellStyle.Font;
            this.BackColor = dataGridViewCellStyle.BackColor;
            this.ForeColor = dataGridViewCellStyle.ForeColor;
        }

        /// <summary>
        /// Method called by the grid on keystrokes to determine if the editing control is
        /// interested in the key or not.
        /// </summary>
        public virtual bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
        {
            switch (keyData & Keys.KeyCode)
            {
                case Keys.Right:
                case Keys.Left:
                case Keys.Tab:
                case Keys.Enter:
                    dataGridViewWantsInputKey = true;
                    return false;
                default:
                    dataGridViewWantsInputKey = false;
                    return true;

            }
        }

        /// <summary>
        /// Returns the current value of the editing control.
        /// </summary>
        public virtual object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            // TODO:  Put in code to validate--change null to empty string
            return this.TextValue;
        }

        /// <summary>
        /// Called by the grid to give the editing control a chance to prepare itself for
        /// the editing session.
        /// </summary>
        public virtual void PrepareEditingControlForEdit(bool selectAll)
        {
            // Put any changes to EllipsesTextbox here....
            // For example,
            txtEnter.MaxLength = 5000;
        }

        #endregion

        /// <summary>
        /// Small utility function that updates the local dirty state and
        /// notifies the grid of the value change.
        /// </summary>
        private void NotifyDataGridViewOfValueChange()
        {
            if (!this.valueChanged)
            {
                this.valueChanged = true;
                this.dataGridView.NotifyCurrentCellDirty(true);
            }
        }

        /// <summary>
        /// Listen to the TextChanged notification to forward the change to the grid.
        /// </summary>
        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            NotifyDataGridViewOfValueChange();
        }
        #endregion


    }
}
//class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;

namespace Test_Win
{
    public class TextBoxButtonColumn : DataGridViewColumn
    {
        public TextBoxButtonColumn()
        {
            this.CellTemplate = new TextBoxButtonCell();
        }

        #region Properties

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                TextBoxButtonCell dataGridViewCustomEditCell = value as TextBoxButtonCell;
                if (value != null && dataGridViewCustomEditCell == null)
                {
                    throw new InvalidCastException(
                        "Value provided for CellTemplate must be of type " +
                        "DataGridViewCustomEditElements.DataGridViewCustomEditCell " +
                        "or derive from it.");
                }
                base.CellTemplate = value;
            }
        }

        /// <summary>
        /// Small utility function that returns the template cell as a DataGridViewEllipsesTextboxCell
        /// </summary>
        private TextBoxButtonCell EllipsesTextboxCellTemplate
        {
            get
            {
                return (TextBoxButtonCell)this.CellTemplate;
            }
        }

        [
         Category("Behavior"),
         DefaultValue(TextBoxButtonCell.DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultMaxLength),
         Description("Indicates the maximum number of characters in the cell.")
        ]
        public int MaxInputLength
        {
            get
            {
                if (this.EllipsesTextboxCellTemplate == null)
                {
                    throw new InvalidOperationException(
                        "Operation cannot be completed because this DataGridViewColumn " +
                        "does not have a CellTemplate.");
                }
                return this.EllipsesTextboxCellTemplate.MaxInputLength;
            }
            set
            {
                if (this.EllipsesTextboxCellTemplate == null)
                {
                    throw new InvalidOperationException(
                        "Operation cannot be completed because this DataGridViewColumn " +
                        "does not have a CellTemplate.");
                }
                // Update the template cell so that the subsequent cloned cells use the new value.
                this.EllipsesTextboxCellTemplate.MaxInputLength = value;
                if (this.DataGridView != null)
                {
                    // Update all the existing DataGridViewEllipsesTextboxCell cells in the column accordingly.
                    DataGridViewRowCollection dataGridViewRows = this.DataGridView.Rows;
                    int rowCount = dataGridViewRows.Count;
                    for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
                    {
                        // Be careful not to unshare rows unnecessarily.
                        // This could have severe performance repercussions.  
                        DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
                        TextBoxButtonCell dataGridViewCell = dataGridViewRow.Cells[this.Index] as TextBoxButtonCell;

                        if (dataGridViewCell != null)
                        {
                            // Call the internal SetMaxLength methos instead of the property to avoid 
                            // invalidation of each cell.  The whole column is invalidated later in a 
                            // single operation for better performance.
                            dataGridViewCell.SetMaxLength(rowIndex, value);
                        }
                    }
                    this.DataGridView.InvalidateColumn(this.Index);
                }
            }
        }

        #endregion

        #region Methods

        #region Override Methods

        public override object Clone()
        {
            TextBoxButtonColumn dataGridViewColumn = base.Clone() as TextBoxButtonColumn;
            if (dataGridViewColumn != null)
            {
            }
            return dataGridViewColumn;
        }

        #endregion

        #endregion


    }
    public class TextBoxButtonCell : DataGridViewTextBoxCell
    {
        #region Default constants for DataGridViewEllipsesTextboxCell
        // Default values for DataGridViewCustomEditCell  
        internal const int DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultMaxLength = 2000;
        // Default dimensions of the static rendering bitmap used for the painting   
        // of the non-edited cells  
        private const int DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultRenderingBitmapWidth = 100;
        private const int DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultRenderingBitmapHeight = 22;
        #endregion

        #region Private Properties

        // Used in TranslateAlignment function
        private static readonly DataGridViewContentAlignment anyRight = DataGridViewContentAlignment.TopRight |
                                                                        DataGridViewContentAlignment.MiddleRight |
                                                                        DataGridViewContentAlignment.BottomRight;
        private static readonly DataGridViewContentAlignment anyCenter = DataGridViewContentAlignment.TopCenter |
                                                                         DataGridViewContentAlignment.MiddleCenter |
                                                                         DataGridViewContentAlignment.BottomCenter;

        // Type of this cell's editing control
        private static Type defaultEditType = typeof(DataGridViewButtonTextboxColumn);

        // The bitmap used to paint the non-edited cells via a call to TextBox.DrawToBitmap
        [ThreadStatic]
        private static Bitmap renderingBitmap;

        // The TextBox control used to paint the non-edited cells via a call to TextBox.DrawToBitmap
        [ThreadStatic]
        private static TextBox paintingTextbox;

        #endregion

        public TextBoxButtonCell()
        {
            // Create a thread specific bitmap used for the painting of the non-edited cells
            if (renderingBitmap == null)
            {
                renderingBitmap = new Bitmap(DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultRenderingBitmapWidth, DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultRenderingBitmapHeight);
            }

            // Create a thread specific EllipsesTextbox control used for the painting of the non-edited cells
            if (paintingTextbox == null)
            {
                paintingTextbox = new TextBox();
                // Some properties only need to be set once for the lifetime of the control:
                paintingTextbox.BorderStyle = BorderStyle.None;
            }
            // Set the Default Properties
            this.MaxInputLength = DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultMaxLength;
        }

        #region Overridden Properties of DataGridViewCell
        [
            DefaultValue(DATAGRIDVIEWELLIPSESTEXTBOXCELL_defaultMaxLength)
        ]
        public override int MaxInputLength
        {
            get
            {
                return base.MaxInputLength;
            }
            set
            {
                if (value < 0 || value > 3000)
                {
                    throw new ArgumentOutOfRangeException("The MaxLength property cannot be smaller than 0 or larger than 3000");
                }
                if (base.MaxInputLength != value)
                {
                    SetMaxLength(this.RowIndex, value);
                    // Assure that the cell or column gets repainted and autosized if needed
                    OnCommonChange();
                }
            }
        }

        // Override the type of the cell's editing control
        public override Type EditType
        {
            get
            {
                return defaultEditType; //type is DataGridViewEllipesesTextboxEditControl
            }
        }

        // No need to override FormattedValueType (type of data on screen) because it is still System.String
        // No need to override ValueType (type of cell's value) because it is still System.String

        /// <summary>  
        /// Returns the current DataGridView EditingControl as a DataGridViewCustomEditControl control  
        /// </summary>  
        private DataGridViewButtonTextboxColumn EditingCustomEdit
        {
            get
            {
                return this.DataGridView.EditingControl as DataGridViewButtonTextboxColumn;
            }
        }
        #endregion

        public override object Clone()
        {
            TextBoxButtonCell dataGridViewCell = base.Clone() as TextBoxButtonCell;
            if (dataGridViewCell != null)
            {
                dataGridViewCell.MaxInputLength = this.MaxInputLength;
                //dataGridViewCell.EnterInformationForm = this.EnterInformationForm;
            }
            return dataGridViewCell;
        }

        /// <summary>
        /// Try using this one to get into edit mode
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClick(DataGridViewCellEventArgs e)
        {
            if (base.DataGridView != null)
            {
                base.DataGridView.BeginEdit(true);
            }
            base.OnClick(e);
        }

        protected override void OnContentClick(DataGridViewCellEventArgs e)
        {
            base.OnContentClick(e);
        }

        /// <summary>
        /// Used to define which keystrokes force the editing control to be shown
        /// </summary>
        public override bool KeyEntersEditMode(KeyEventArgs e)
        {
            // Need to determine if we want any KEYS to allow us to enter edit mode from 
            // within this cell.  Possibilities include 'Enter'.
            if (e.KeyCode == Keys.Enter)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Used to initialize the editing control 
        /// </summary>
        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue,
            DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            DataGridViewButtonTextboxColumn ellipsesTextBox = this.DataGridView.EditingControl as DataGridViewButtonTextboxColumn;
            if (ellipsesTextBox != null)
            {
                // Set the max length of the textbox to the same as in for the cell and make it multiline
                ellipsesTextBox.MaxLength = this.MaxInputLength;
                string initialFormattedValueStr = initialFormattedValue as string;
                // If the cell contains data, copy it to the new multiline TextBox control
                if (initialFormattedValueStr == null)
                {
                    ellipsesTextBox.TextValue = string.Empty;
                }
                else
                {
                    ellipsesTextBox.TextValue = initialFormattedValueStr;
                }
                // Set the value of the EnterInformationForm
                //ellipsesTextBox.EnterInformationForm = this.EnterInformationForm;
            }
        }

        /// <summary>
        /// Used to position and size the editing control within the DataGridView
        /// </summary>
        public override 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);
            editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle);
            this.DataGridView.EditingControl.Location
                = new Point(editingControlBounds.X, editingControlBounds.Y);
            this.DataGridView.EditingControl.Size
                = new Size(editingControlBounds.Width, editingControlBounds.Height);
        }

        /// <summary>
        /// Used to clean up the cell before detaching the editing control
        /// </summary>
        [
            EditorBrowsable(EditorBrowsableState.Advanced)
        ]
        public override void DetachEditingControl()
        {
            DataGridView dataGridView = this.DataGridView;
            if (dataGridView == null || dataGridView.EditingControl == null)
            {
                throw new InvalidOperationException(
                    "Cell is detached or its grid has no editing control.");
            }

            DataGridViewButtonTextboxColumn ellipsesTextBox = dataGridView.EditingControl as DataGridViewButtonTextboxColumn;
            if (ellipsesTextBox != null)
            {
                // Editing controls get recycled. Indeed, when a DataGridViewEllipsesTextboxCell 
                // cell gets edited after another DataGridViewCustomEditCell cell, the same editing  
                // control gets reused for performance reasons (to avoid an unnecessary control  
                // destruction and creation).  Here the undo buffer of the TextBox control gets 
                // cleared to avoid interferences between the editing sessions.
                DataGridViewButtonTextboxColumn textBox = ellipsesTextBox as DataGridViewButtonTextboxColumn;
            }

            base.DetachEditingControl();
        }

        /// <summary>
        /// Corrects value of cell size to account for scroll buttons
        /// </summary>
        protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle,
            int rowIndex, Size constraintSize)
        {
            if (this.DataGridView == null)
            {
                return new Size(-1, 01);
            }

            Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize);
            if (constraintSize.Width == 0)
            {
                const int ButtonWidth = 16; // Account for the width of the scroll buttons
                const int ButtonMargin = 8; // Account for some blank pixels between the text and buttons.
                preferredSize.Width += ButtonWidth + ButtonMargin;
            }
            return preferredSize;
        }

        /// <summary>
        /// Makes sure that error icon does not overlap button
        /// </summary>
        protected override Rectangle GetErrorIconBounds(Graphics graphics,
            DataGridViewCellStyle cellStyle, int rowIndex)
        {
            const int ButtonWidth = 16;

            Rectangle errorIconBounds = base.GetErrorIconBounds(graphics, cellStyle, rowIndex);
            if (this.DataGridView.RightToLeft == RightToLeft.Yes)
            {
                errorIconBounds.X = errorIconBounds.Left + ButtonWidth;
            }
            else
            {
                errorIconBounds.X = errorIconBounds.Left - ButtonWidth;
            }
            return errorIconBounds;
        }

        // No need to override the GetFormattedValue method since text is string
        // No need to override ToString method or Paint method


        internal void SetMaxLength(int rowIndex, int value)
        {
            base.MaxInputLength = value;
        }

        internal void SetEnterInformationForm(int rowIndex)
        {
            if (OwnsEditingCustomEdit(rowIndex))
            {
            }
        }

        /// <summary>
        /// Used to determine the rectangle that represents the size of the editing cell
        /// </summary>
        /// <param name="editingControlBounds">Rectangle representing the editing cell</param>
        private Rectangle GetAdjustedEditingControlBounds(Rectangle editingControlBounds, DataGridViewCellStyle cellStyle)
        {
            // Determine the height of this control and how to expand it as necessary
            // Add a 1 pixel padding on the left and right of the editing control
            editingControlBounds.X += 1;
            editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2);

            //Adjust the vertical location of the editing control
            int preferredHeight = cellStyle.Font.Height + 3;
            if (preferredHeight < editingControlBounds.Height)
            {
                switch (cellStyle.Alignment)
                {
                    case DataGridViewContentAlignment.MiddleLeft:
                    case DataGridViewContentAlignment.MiddleCenter:
                    case DataGridViewContentAlignment.MiddleRight:
                        editingControlBounds.Y += (editingControlBounds.Height - preferredHeight) / 2;
                        break;
                    case DataGridViewContentAlignment.BottomLeft:
                    case DataGridViewContentAlignment.BottomCenter:
                    case DataGridViewContentAlignment.BottomRight:
                        editingControlBounds.Y += editingControlBounds.Height - preferredHeight;
                        break;
                }
            }
            return editingControlBounds;
        }

        /// <summary>
        /// Called when a cell characteristic that affects its rendering and/or preferred size has changed.
        /// This implementation only takes care of repainting the cells. The DataGridView's autosizing 
        /// methods also need to be called in cases where some grid elements autosize.
        /// </summary>
        private void OnCommonChange()
        {
            if (this.DataGridView != null && !this.DataGridView.IsDisposed && !this.DataGridView.Disposing)
            {
                if (this.RowIndex == -1)
                {
                    // Invalidate and autosize column
                    this.DataGridView.InvalidateColumn(this.ColumnIndex);
                }
                else
                {
                    // The DataGridView control exposes a public method called UpdateCellValue
                    // that invalidates the cell so that it gets repainted and also triggers all
                    // the necessary autosizing: the cell's column and/or row, the column headers
                    // and the row headers are autosized depending on their autosize settings.
                    this.DataGridView.UpdateCellValue(this.ColumnIndex, this.RowIndex);
                }
            }
        }

        /// <summary>
        /// Determines whether this cell, at the given row index, shows the grid's editing control or not.
        /// The row index needs to be provided as a parameter because this cell may be shared among 
        /// multiple rows.
        /// </summary>
        private bool OwnsEditingCustomEdit(int rowIndex)
        {
            if (rowIndex == -1 || this.DataGridView == null)
            {
                return false;
            }
            DataGridViewButtonTextboxColumn customEditControl = this.DataGridView.EditingControl as DataGridViewButtonTextboxColumn;
            return customEditControl != null
                && rowIndex == ((IDataGridViewEditingControl)customEditControl).EditingControlRowIndex;
        }


    }
}
 
Share this answer
 
Comments
EdikSail 9-Nov-16 9:29am    
is it full?
EdikSail 9-Nov-16 9:29am    
I want to use this code, but I think it is not complete
EdikSail 9-Nov-16 9:30am    
there is a bug near Implements IDataGridViewEditingControl
EdikSail 9-Nov-16 9:30am    
InitializeComponent() is not declared

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900