Ограничение на вводимые значения в DataGridView при помощи обработчика нажатия клавиши
Помогите, пожалуйста, разобраться с ограничением на вводимые в ячейку DataGridView при использовании C++. Необходимо, чтобы в ячейку можно было ввести только значения 0 или 1.
Пытаюсь решить это через обработчики события нажатия клавиши. Отыскала, как подобная проблема решалась на C#, попыталась напрямую "перевести" на C++, в итоге ожидаемо получила ошибку об отсутствии списка аргументов у функции и предложение создать ссылку на функцию.
Код:
private: System::Void dataGridView1_EditingControlShowing(System::Object^ sender, System::Windows::Forms::DataGridViewEditingControlShowingEventArgs^ e) {
//здесь возникает ошибка, связанная с отсутствием аргументов у функции
e->Control->KeyPress += gcnew KeyPressEventHandler(dataGridView1_KeyPress);
}
private: System::Void dataGridView1_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e) {
if (e->KeyChar != '0' || e->KeyChar != '1')
{
e->Handled = true;
}
}
//здесь возникает ошибка, связанная с отсутствием аргументов у функции
e->Control->KeyPress += gcnew KeyPressEventHandler(dataGridView1_KeyPress);
}
private: System::Void dataGridView1_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e) {
if (e->KeyChar != '0' || e->KeyChar != '1')
{
e->Handled = true;
}
}
Если пытаюсь вместо самой функции assess_KeyPress использовать указатель на нее, то получаю ошибку :
error C3352: void trydgv::Form1::dataGridView1_KeyPress(System::Object ^,System::Windows::Forms::KeyPressEventArgs ^): указанная функция не соответствует типу делегата "void (System::Object ^,System::Windows::Forms::KeyPressEventArgs ^)"
Уже со всех сторон пыталась решить и созданием объекта и ссылкой на него. Помогите, пожалуйста, понять, как все же правильно использовать здесь функцию-обработчик или ссылку на нее.
Заранее спасибо!
В этом примере ввод "0 и 1" только для Column2
Код:
private:
bool nonNumberEntered;
private: System::Void dataGridView1_EditingControlShowing(System::Object^ sender, System::Windows::Forms::DataGridViewEditingControlShowingEventArgs^ e) {
if ( this->dataGridView1->CurrentCell->OwningColumn->Name->Equals(L"Column2"))
{
e->Control->KeyPress -= gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::Control_KeyPress);
e->Control->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::Control_KeyPress);
}
else
{
e->Control->KeyPress -= gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::Control_KeyPress);
}
}
void Control_KeyPress(System::Object^ /*sender*/, System::Windows::Forms::KeyPressEventArgs^ e){
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if ( e->KeyChar < 48 || e->KeyChar > 49 )
{
// Determine whether the keystroke is a number from the keypad.
if ( e->KeyChar < 98 || e->KeyChar > 97)
{
// Determine whether the keystroke is a backspace.
if ( e->KeyChar != 8 )
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
// Check for the flag being set in the KeyDown event.
if ( nonNumberEntered == true )
{ // Stop the character from being entered into the control since it is non-numerical.
e->Handled = true;
}
//If shift key was pressed, it's not a number.
if (Control::ModifierKeys == Keys::Shift) {
nonNumberEntered = true;
}
}
private: System::Void dataGridView1_CellClick(System::Object^ sender, System::Windows::Forms::DataGridViewCellEventArgs^ e) {
try{
this->label1->Text=L"Столбец :"+ dataGridView1->Columns[e->ColumnIndex]->Index.ToString();
this->label2->Text=L"Строка :"+ dataGridView1->Rows[e->RowIndex]->Index.ToString();
this->label3->Text=L"Имя столбца :"+ dataGridView1->Columns[ e->ColumnIndex ]->Name;
}
catch(...)
{}
}
bool nonNumberEntered;
private: System::Void dataGridView1_EditingControlShowing(System::Object^ sender, System::Windows::Forms::DataGridViewEditingControlShowingEventArgs^ e) {
if ( this->dataGridView1->CurrentCell->OwningColumn->Name->Equals(L"Column2"))
{
e->Control->KeyPress -= gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::Control_KeyPress);
e->Control->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::Control_KeyPress);
}
else
{
e->Control->KeyPress -= gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::Control_KeyPress);
}
}
void Control_KeyPress(System::Object^ /*sender*/, System::Windows::Forms::KeyPressEventArgs^ e){
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if ( e->KeyChar < 48 || e->KeyChar > 49 )
{
// Determine whether the keystroke is a number from the keypad.
if ( e->KeyChar < 98 || e->KeyChar > 97)
{
// Determine whether the keystroke is a backspace.
if ( e->KeyChar != 8 )
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
// Check for the flag being set in the KeyDown event.
if ( nonNumberEntered == true )
{ // Stop the character from being entered into the control since it is non-numerical.
e->Handled = true;
}
//If shift key was pressed, it's not a number.
if (Control::ModifierKeys == Keys::Shift) {
nonNumberEntered = true;
}
}
private: System::Void dataGridView1_CellClick(System::Object^ sender, System::Windows::Forms::DataGridViewCellEventArgs^ e) {
try{
this->label1->Text=L"Столбец :"+ dataGridView1->Columns[e->ColumnIndex]->Index.ToString();
this->label2->Text=L"Строка :"+ dataGridView1->Rows[e->RowIndex]->Index.ToString();
this->label3->Text=L"Имя столбца :"+ dataGridView1->Columns[ e->ColumnIndex ]->Name;
}
catch(...)
{}
}
см. пример
Правильно будет делать событие KeyPress не на DataGridView, а на ячейки таблицы т.к не все ячейки имеют одинаковые параметры ВВОДА.
Код:
if ( e->KeyCode < Keys::D0 || e->KeyCode > Keys::D9 )
Знакомилась с этим примером, чтобы ограничить вводимые значения в TextBox. Там все работало без вопросов:)
В DataGridView почему-то при редактировании ячейки нажатие клавиши за таковое не принимается, что подтвердилось при отладке. Если на том же DataGridView переходить между ячейками путем нажатия клавиш влево-вправо, вверх-вниз - их он обрабатывает как нажатие клавиши и вполне корректно загружает обработчики KeyDown или KeyPress, но вот при нажатии клавиш с символьными значениями, DataGridView сразу переходит в режим редактирования и обработчик нажатия клавиши не запускает.
Смотрела, как решается данная проблема здесь и здесь но вот под С++ переделать не удалось корректно.
Не знаю, как повесить событие на ячейку, тем более что ячейки определяются только в момент построения формы (то есть при проектировании формы еще не определено, сколько столбцов и строк, эти параметры задаются пользователем).
Можно, конечно, решить эту задачу путем проверки уже введенного значения и стиранием его, если это не 1 или 0, но хочется разобраться, как можно именно запретить ввод.
Правильно будет делать событие KeyPress не на DataGridView, а на ячейки таблицы т.к не все ячейки имеют одинаковые параметры ВВОДА.
Код:
private: System::Void dataGridView1_CellClick(System::Object^ sender, System::Windows::Forms::DataGridViewCellEventArgs^ e) {
//if ( this->dataGridView1->Columns[ e->ColumnIndex ]->Name->Equals( "Column2" ));
{
//if ( this->dataGridView1->Columns[ e->ColumnIndex ]->Name->Equals( "Column2" ));
{
Осталось только отфильтровать ввод с клавы.
Попробовала в событие CellClick (хотя оно и срабатывает только на щелчок мыши) вставить примерно такой код - посмотреть, скомпилируется или нет
Код:
dataGridView1->Rows[e->RowIndex]->Cells[e->ColumnIndex]->KeyPress += gcnew System::Windows::Forms::KeyEventHandler(this, &Form1::dataGridView1_KeyDown);
Получаю ошибку: error C2039: KeyPress: не является членом "System::Windows::Forms::DataGridViewCell"
Если пытаюсь прицепить к самому аргументу e
Код:
e->KeyPress += gcnew System::Windows::Forms::KeyEventHandler(this, &Form1::dataGridView1_KeyDown);
И в инициализации компонентов тоже не объявить, так как для класса ячейки, по-видимому, не существует обработчика нажатия кнопки.
Попробую еще использовать KeyEntersEditMode с передачей значения нажаттой кнопки сразу в таблицу. Но это все же несколько не то.
Вот эта инициализация функции как раз то, чего не хватало для понимания с самого начала
Код:
e->Control->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::Control_KeyPress);