110,536
社区成员
发帖
与我相关
我的任务
分享
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
{
string temp = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
getTargetStr(temp,5); //我上面写的那个方法
}
}
你非要那个固定长的效果,那个列,动态加载textbox,如下
private void Form1_Load(object sender, EventArgs e)
{
TextBox text = new TextBox();
text.Text = "hahha";
text.Name = "tbx1"; //一万个,就用tbx10000
text.TextChanged += new EventHandler(setText);
dataGridView1.Rows[0].Cells[0].Value = text;
dataGridView1.Controls.Add(text);
}
private void setText(object sender,EventArgs e)
{
TextBox currText = (TextBox)sender;
if(currText.Text.Trim()!=string.Empty)
{
currText.Text = getTargetStr(currText.Text.Trim(), 5);
currText.Select(5, 0);
}
}
我这没数据,只好加到0行0列
超过5个就不动了,和设置maxLength一样的效果
cell可以放任意对象
private string getTargetStr(string input,int maxLen)
{
string output = string.Empty;
int num = 0;
for (int i = 0; i < input.Length; i++)
{
if ((int)input[i] >= 0x4E00 && (int)input[i] <= 0x9fa5)
{
num += 2;
}
else
{
num++;
}
if (num <= maxLen)
{
output += input[i];
}
else
{
break;
}
}
return output;
}
//textbox1_textChange里
textBox1.Text = getTargetStr(textBox3.Text.Trim(),5);
textBox1.Select(5, 0);
public DataGridViewTextBoxEditingControl CellEdit = null;
private void dataGridView1_EditingControlShowing_1(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if ((this.dataGridView1.CurrentCellAddress.X == 0) || (this.dataGridView1.CurrentCellAddress.X == 1))//获取当前处于活动状态的单元格索引
{
CellEdit = (DataGridViewTextBoxEditingControl)e.Control;
CellEdit.SelectAll();
CellEdit.KeyPress += Cells_KeyPress; //绑定事件
}
}
private void Cells_KeyPress(object sender, KeyPressEventArgs e) //自定义事件
{
if (System.Text.Encoding.Default.GetBytes((sender as TextBox).Text).Length >= 5)
{
e.Handled = true;
}
if (e.KeyChar == '\b')
{
e.Handled = false;
}
}
private void dataGridView1_CellValueChanged_1(object sender, DataGridViewCellEventArgs e)
{
if (this.dataGridView1.CurrentCellAddress.X == 0)//获取当前处于活动状态的单元格索引
{
if (System.Text.Encoding.Default.GetBytes(this.dataGridView1.CurrentCell.Value.ToString()).Length > 5)
{
MessageBox.Show("仅能输入5个字节,多余数据将被舍弃。", "提示");
string txt = this.dataGridView1.CurrentCell.Value.ToString();
this.dataGridView1.CurrentCell.Value = SubstringByte(txt, 0, 5);
dataGridView1.BeginEdit(false);
TextBox tb = (TextBox)dataGridView1.EditingControl;
tb.SelectionStart = 5;//0表示定位到最前面
}
}
}
private void dataGridView1_CurrentCellDirtyStateChanged_1(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private static Encoding _encoding = System.Text.Encoding.Default;
private string SubstringByte(string text, int startIndex, int length)
{
byte[] bytes = _encoding.GetBytes(text);
return _encoding.GetString(bytes, startIndex, length);
}
这种方法的问题是:当输入超过指定字节后,触发提示窗口,点击确定后,这条指令this.dataGridView1.CurrentCell.Value = SubstringByte(txt, 0, 5);不会立即将单元格的内容转成5字节,而是在用户点击其它单元格以后才会变成截取后的内容,这也是与Textbox控件的不同之处,此方法复制粘贴也可以适用,但每次都弹出提示框,如果复制粘贴10字节文字,不用鼠标选中一起删除,就会有n多个提示框,比如我复制粘贴“123456789”执行this.dataGridView1.CurrentCell.Value = SubstringByte(txt, 0, 5)后,单元格的内容仍然是“123456789”,然后按backspace每次删除1字节(如6、7、8、9),就会还有4个提示框,我觉得交互不大好
private int verifiedType(string input)
{
Match match = Regex.Match(input, @"^([\u4e00-\u9fa5]+)$|^([a-z0-9]+)$");
if(match.Groups[1].Value!=string.Empty)
{
return 0;
}
else if(match.Groups[2].Value!=string.Empty)
{
return 1;
}
else
{
return -1;
}
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
string tempText = textBox3.Text.Trim();
if(verifiedType(tempText) == 0)
{
if (tempText.Length > 2)
{
textBox3.Text = tempText.Substring(0, 2);
textBox3.Select(2, 0);
}
}
else if(verifiedType(tempText) == 1)
{
if (verifiedType(tempText) == 1 && tempText.Length > 5)
{
textBox3.Text = tempText.Substring(0, 5);
textBox3.Select(5, 0);
}
}
else
{
textBox3.Text = ""; //若是字母数字+汉字,则清空
}
}