Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
392 views
in Technique[技术] by (71.8m points)

c# - how to add ellipse button and textbox in current cell of datagridview in winforms

i want to add an ellipse button and textbox control in current cell of my datagridview. By clicking on ellipse button i want to open a custom calculator and result of it will show in textbox. I have already develop custom calculator. I just want to show ellipse button and textbox control in current selected cell. If i leave a cell, then value of textbox control should assign to cell which has lefted. Following is the screenshot.

enter image description here

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to create custom EditingControl, Cell and Column classes as described here: http://msdn.microsoft.com/en-us/library/aa730881(v=vs.80).aspx

I've created sample application for you. See download link below.
Contents:

  • TextButton control
    UserControl containing TextBox without border and simple button.
    enter image description here

  • Simple Edit Form
    Any simple dialog form, returning DialogResult.
    enter image description here

  • DataGridViewTextButtonEditingControl class
    We need to inherit from our TextButton control and to implement IDataGridViewEditingControl interface here.

     internal class DataGridViewTextButtonEditingControl : TextButton, IDataGridViewEditingControl
     {
         public DataGridViewTextButtonEditingControl()
         {
             InnerTextBox.TextChanged += (o, e) => NotifyDataGridViewOfValueChange();
         }
    
         public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
         {
             Font = dataGridViewCellStyle.Font;
             if (dataGridViewCellStyle.BackColor.A < 255)
             {
                 Color opaqueBackColor = Color.FromArgb(255, dataGridViewCellStyle.BackColor);
                 BackColor = opaqueBackColor;
                 EditingControlDataGridView.EditingPanel.BackColor = opaqueBackColor;
             }
             else
             {
                 BackColor = dataGridViewCellStyle.BackColor;
             }
             ForeColor = dataGridViewCellStyle.ForeColor;
         }
    
         public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
         {
             TextBox textBox = InnerTextBox;
             switch (keyData & Keys.KeyCode)
             {
                 case Keys.Right:
                     {
                         if (textBox != null)
                         {
                             // If the end of the selection is at the end of the string,
                             // let the DataGridView treat the key message
                             if ((RightToLeft == RightToLeft.No && !(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length)) ||
                                 (RightToLeft == RightToLeft.Yes && !(textBox.SelectionLength == 0 && textBox.SelectionStart == 0)))
                             {
                                 return true;
                             }
                         }
                         break;
                     }
    
                 case Keys.Left:
                     {
                         if (textBox != null)
                         {
                             // If the end of the selection is at the begining of the string
                             // or if the entire text is selected and we did not start editing,
                             // send this character to the dataGridView, else process the key message
                             if ((RightToLeft == RightToLeft.No && !(textBox.SelectionLength == 0 && textBox.SelectionStart == 0)) ||
                                 (RightToLeft == RightToLeft.Yes && !(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length)))
                             {
                                 return true;
                             }
                         }
                         break;
                     }
    
                 case Keys.Home:
                 case Keys.End:
                     {
                         // Let the grid handle the key if the entire text is selected.
                         if (textBox != null)
                         {
                             if (textBox.SelectionLength != textBox.Text.Length)
                             {
                                 return true;
                             }
                         }
                         break;
                     }
    
                 case Keys.Delete:
                     {
                         // Let the grid handle the key if the carret is at the end of the text.
                         if (textBox != null)
                         {
                             if (textBox.SelectionLength > 0 ||
                                 textBox.SelectionStart < textBox.Text.Length)
                             {
                                 return true;
                             }
                         }
                         break;
                     }
             }
             return !dataGridViewWantsInputKey;
         }
    
         public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
         {
             return Text; // Convert.ChangeType(Text, typeof(int));
         }
    
         public void PrepareEditingControlForEdit(bool selectAll)
         {
             if (selectAll)
             {
                 InnerTextBox.SelectAll();
             }
             else
             {
                 // Do not select all the text, but
                 // position the caret at the end of the text
                 InnerTextBox.SelectionStart = InnerTextBox.Text.Length;
             }
         }
    
         public DataGridView EditingControlDataGridView { get; set; }
         public object EditingControlFormattedValue { get; set; }
         public int EditingControlRowIndex { get; set; }
         public bool EditingControlValueChanged { get; set; }
         public Cursor EditingPanelCursor { get; private set; }
         public bool RepositionEditingControlOnValueChange { get; private set; }
    
         protected override void OnTextChanged(EventArgs e)
         {
             base.OnTextChanged(e);
             NotifyDataGridViewOfValueChange();
         }
    
         private void NotifyDataGridViewOfValueChange()
         {
             if (!EditingControlValueChanged)
             {
                 EditingControlValueChanged = true;
                 EditingControlDataGridView.NotifyCurrentCellDirty(true);
             }
         }
     }
    
  • DataGridViewTextButtonCell class
    We need to inherit from the DataGridViewCell to implement DataGridViewTextButtonEditingControl initialization, cell painting and (important!) cloning.
    Without overriding the Clone() method, we will not be able to set properties of a newly created instances.

     internal sealed class DataGridViewTextButtonCell : DataGridViewCell
     {
         private const byte DATAGRIDVIEWTEXTBOXCELL_horizontalTextOffsetLeft = 3;
         private const byte DATAGRIDVIEWTEXTBOXCELL_horizontalTextOffsetRight = 4;
         private const byte DATAGRIDVIEWTEXTBOXCELL_horizontalTextMarginLeft = 0;
         private const byte DATAGRIDVIEWTEXTBOXCELL_horizontalTextMarginRight = 0;
         private const byte DATAGRIDVIEWTEXTBOXCELL_verticalTextOffsetTop = 2;
         private const byte DATAGRIDVIEWTEXTBOXCELL_verticalTextOffsetBottom = 1;
         private const byte DATAGRIDVIEWTEXTBOXCELL_verticalTextMarginTopWithWrapping = 1;
         private const byte DATAGRIDVIEWTEXTBOXCELL_verticalTextMarginTopWithoutWrapping = 2;
         private const byte DATAGRIDVIEWTEXTBOXCELL_verticalTextMarginBottom = 1;
    
         // Type of this cell's editing control
         private static readonly Type defaultEditType = typeof(DataGridViewTextButtonEditingControl);
         // Type of this cell's value. The formatted value type is string, the same as the base class DataGridViewTextBoxCell
         private static readonly Type defaultValueType = typeof(string);
    
         public override object Clone()
         {
             DataGridViewTextButtonCell cell = base.Clone() as DataGridViewTextButtonCell;
             if (cell != null)
             {
                 cell.ButtonClickHandler = ButtonClickHandler;
             }
             return cell;
         }
    
         /// <summary>
         /// Adjusts the location and size of the editing control given the alignment characteristics of the cell
         /// </summary>
         private Rectangle GetAdjustedEditingControlBounds(Rectangle editingControlBounds, DataGridViewCellStyle cellStyle)
         {
             // 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;
         }
    
         public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
         {
             base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
             TextButton textButton = DataGridView.EditingControl as TextButton;
             if (textButton != null)
             {
                 //textButton.BorderStyle = BorderStyle.None;
                 string initialFormattedValueStr = initialFormattedValue as string;
                 textButton.Text = initialFormattedValueStr;
                 if (ButtonClickHandler != null)
                     textButton.ButtonClick += ButtonClickHandler;
             }
         }
    
         public override void DetachEditingControl()
         {
             base.DetachEditingControl();
             TextButton textButton = DataGridView.EditingControl as TextButton;
             if (textButton != null)
             {
                 textButton.ClearUndo();
                 if (ButtonClickHandler != null)
                     textButton.ButtonClick -= ButtonClickHandler;
             }
         }
    
         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);
             DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y);
             DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height);
         }
    
         public DataGridViewTextButtonEditingControl EditingControl
         {
             get { return DataGridView == null ? null : DataGridView.EditingControl as DataGridViewTextButtonEditingControl; }
         }
    
         public override Type EditType
         {
             ge

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...