2

DataGridView有源设置为SortableBindingList. 在这种形式中,有列Comment,我需要防止用户插入一些字符,从而进行验证。

我想要做的是,每当用户输入无效值时,系统都会通知他(OnNotification( 'You entered wrong comment');)并强制他/她保持编辑模式。

到目前为止,我构建了这样的解决方案:

void MyDataGridView_CellEndEdit( object sender, DataGridViewCellEventArgs e )
{
    if (e.ColumnIndex == ColumnComment.Index) {
        object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        if( (data != null) && (!CommentIsValid( data.ToString()))){
            CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex];
            BeginEdit( true );

            // My notification method
            OnNotification( String.Format( "Comment `{0}` contains invalid characters) );
            return;
        }
    }
}

我对此有以下问题:

  • OnCellValidating仅在整个表单关闭或当前行更改时触发,而不是在我完成单个单元格的编辑后触发,因此我已将 check 放入CellEndEdit.
  • 当我使用Enter/Esc结束编辑时,它按预期工作。
  • 当我使用鼠标单击另一行时,单元格保持编辑模式,但另一行被选中。
  • 当我尝试使用Enter(显示无效评论通知)然后Esc(取消编辑)它使用推送的值Enter(因为编辑模式已完成)。

所以我的问题是

  • 如何CellValidating在每次单元格编辑后触发,而不是在表单关闭时触发
  • 即使在鼠标单击后如何防止CurrentRow和更改?CurrentCell
  • 如何强制单元格保持编辑模式?
4

3 回答 3

1

当我使用鼠标单击另一行时,单元格保持编辑模式,但另一行被选中。

在这里,我会使用一个全局布尔值,bool isInvalidState比如说和一个全局DataGridViewCell = invalidCell对象。在默认状态下,您可以设置isInvalidState = falseinvalidCell = null。然后使用

private bool OnNotification(string cellValue)
{
    // Check for error.
    if (error)
        return false;
}

然后在上面的方法中

void MyDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == ColumnComment.Index) {
        object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        if((data != null) && (!CommentIsValid(data.ToString()))){
            CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex];
            BeginEdit(true);

            // My notification method
            isInvalidState = OnNotification(
                String.Format("Comment `{0}` contains invalid characters));
            if (isInvalidState)
                invalidCell = MyDataGridView[e.RowIndex, e.ColumnIndex];
            return;
        }
    }
}

CellContentClick现在,在您的设备上连接一个事件DataGridView并检查是否isInvalidState == true

private void MyDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (isInvlaidState)
    {
        isInvalidState = false;
        MyDataGridView.CurrentCell = invalidCell;
        invalidCell = null;
        return;
    }
    // Do other stuff here.
}

当我尝试使用 Enter (显示无效评论通知)然后 Esc (取消编辑)时,它使用 Enter 推送的值(因为编辑模式已完成)。

我不确定这个问题;您可能必须处理KeyDown事件并捕获转义键 - 以不同的方式处理它。

我希望这有帮助。

于 2013-04-10T08:22:38.713 回答
0

尝试这样的事情。它会起作用的。

private void datagridview1_dataGridview_CellValidating
(object sender, DataGridViewCellValidatingEventArgs e) 
{
    if (datagridview1_dataGridview.Rows[e.RowIndex].Cells[2].Value.Equals(""))
    {
         MessageBox.Show("Product name should not be empty", "Error");
         datagridview1_dataGridview.CurrentCell = datagridview1_dataGridview.Rows[e.RowIndex].Cells[2];
         datagridview1_dataGridview.CurrentCell.Selected = true;
    }
}
于 2013-04-10T08:07:08.767 回答
0

不幸的是,MoonKnight 的解决方案对我来说并不完全有效,因为CellContentClick事件处理程序中的代码从未将控件设置回正在验证其值的单元格,当它具有无效值时。尽管如此,考虑到他对使用全局变量的宝贵提示,isInvalidStateinvalidCell帮助我构建了以下解决方案,该解决方案完全按照 OP 中的要求工作。

CellValidating以正确的方式使用和的组合CellValidated解决问题如下:

CellValidating事件处理程序中进行数据验证。设置isInvalidState标志和cellWithInvalidUserInput变量(注意:我将其重命名invalidCellcellWithInvalidUserInput):

private void MyDataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    var cellUnderConsideration = MyDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];

    if (!ValidateCurrentCellValue(cellUnderConsideration)) 
    {               
       OnNotification( String.Format( "Comment `{0}` contains invalid characters) );
       //Or MessageBox.Show("your custom message");

       isInvalidState = true;
       cellWithInvalidUserInput = cellUnderConsideration;
       e.Cancel = true;                    
    }
}

数据验证功能:

bool isInvalidState;
DataGridViewCell cellWithInvalidUserInput;
private bool ValidateCurrentCellValue(DataGridViewCell cellToBeValidated)
{
    //return 'true' if valid, 'false' otherwise
}

CellValidated在事件处理程序内的 UI 控件上执行所需的操作:

private void MyDataGridView_CellValidated(object sender, DataGridViewCellEventArgs e)
{
    if (isInvalidState)
    {
        isInvalidState = false;

        if (cellWithInvalidUserInput != null && cellWithInvalidUserInput.RowIndex > -1)
        {
            MyDataGridView.CurrentCell = cellWithInvalidUserInput;
            MyDataGridView.CurrentCell.Selected = true;
            MyDataGridView.BeginEdit(true);
        }

        cellWithInvalidUserInput = null;
    }
} 
于 2017-09-05T20:23:08.673 回答