Захват первого символа при входе в режим редактирования - пользовательский элемент управления для редактирования в DataGridView - PullRequest
4 голосов
/ 17 декабря 2008

Я размещаю пользовательский элемент управления для редактирования в DataGridView, который для записи представляет собой TextBox и Button вместе в UserControl. Я унаследовал от DataGridViewColumn для нового столбца и DataGridViewTextBoxCell для новой ячейки.

При обычном DataGridViewTextBoxCell, если вы нажмете клавишу, когда ячейка будет в фокусе, начнется режим редактирования и введенный вами символ появится в TextBoxEditingControl. Однако в моей унаследованной ячейке при нажатии клавиш не передается значение. (На самом деле, вы должны вручную передать текущее значение ячейки в InitializeEditingControl, иначе вообще ничего не появится.) Итак, первый введенный вами символ (тот, который начинает режим редактирования) теряется.

Я пытался OnKeyPress, OnKeyDown и OnKeyUp в DataGridViewCell, но их никогда не вызывали. Однако, KeyEntersEditMode, кажется, вызывается, и только тогда, когда он проверяет нажатие клавиши, так что это может быть хорошим началом. Тогда возникает проблема, как перевести KeyEventArgs в char. Это тривиально для алфавита и цифр, но поскольку не все клавиатуры созданы равными, обработка других клавиш в лучшем случае сложна и сложна. Если есть класс конвертера, который будет делать это автоматически, пожалуйста, просветите меня.

Кто-нибудь еще сталкивался с этой проблемой или нашел хороший обходной путь?

Примечание. Эта проблема возникает, если для EditMode установлено любое изменение EditOnKeystroke. Установка EditOnEnter является допустимым обходным решением для моего проекта, но я также хотел бы эмулировать поведение по умолчанию TextBoxEditingControl.

Ответы [ 4 ]

1 голос
/ 01 июля 2009

Мое решение - переопределить OnKeyPress на пользовательском UserControl.

protected override void OnKeyPress(KeyPressEventArgs e)
{
  _textBox.Text = e.KeyChar.ToString();
  _textBox.SelectionStart = 1;
  _textBox.SelectionLength = 0;
  base.OnKeyPress(e);
}
1 голос
/ 09 июня 2009

Попробуйте установить для KeyPreview пользовательского элемента управления значение true. Затем проверьте, запускает ли клавиша, которая запускает процесс редактирования, нажатие клавиши даже для пользовательского элемента управления. Если это так, вы можете просто сохранить и назначить символ, как только текстовый элемент управления перейдет в режим редактирования.

0 голосов
/ 25 февраля 2012

Чтобы получить первый символ в вашем TextBox, сделайте это:

1) Добавьте «Imports System.Runtime.InteropServices» или используйте, если вы предпочитаете C #

2) Добавить сопоставление в SendMessage в user32.dll

VB.Net example:
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function

C# example:
[DllImport("USER32.DLL", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

3) Перенаправить ключ на ваш TextBox из UserControl

Protected Overrides Function ProcessKeyEventArgs(ByRef m As System.Windows.Forms.Message) As Boolean
    SendMessage(Me.ComboBox.Handle, m.Msg, m.WParam, m.LParam)
    Return True
End Function

protected override bool ProcessKeyEventArgs(ref Message m)
{
    SendMessage(textBox.Handle, m.Msg, m.WParam, m.LParam);
    return true;
}

4) На странице Microsoft есть пример с DataGridViewNumericUpDown здесь , загрузите исходный код.

5) Готово.

0 голосов
/ 31 января 2011

Привет Сегодня у меня была такая же проблема. Мое решение состоит в том, чтобы переопределить KeyEntersEditMode в CustomCell и поместить туда какой-нибудь алгоритм для преобразования или определения допустимости символа для передачи в элемент управления для редактирования. Затем я сохраняю это значение как частную переменную. Я переопределяю метод InitializeEditingControl и использую мое сохраненное значение в качестве начального значения для элемента управления. После его использования я установил его на нуль, чтобы потом ничто его не использовало.


private string startString;
public override bool KeyEntersEditMode(KeyEventArgs e)
{
    var result = base.KeyEntersEditMode(e);
    if (e.KeyData == Keys.D1)
    {
        startString = "1";
    }
    return result;
}

public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
    if(startString != null)
    {
        initialFormattedValue = startString;
        startString = null;
    }
    base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
    var c = this.DataGridView.EditingControl as MyEditingControl;
    string initialFormattedValueStr = initialFormattedValue as string;
    if (initialFormattedValueStr == null)
    {
        c.Text = string.Empty;
    }
    else
    {
        c.Text = initialFormattedValueStr;
        c.SelectionStart = initialFormattedValueStr.Length;
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...