2008-12-17 10 views
4

Je hébergement un contrôle d'édition personnalisée dans un DataGridView, qui, pour l'enregistrement est un TextBox et Button ensemble dans un UserControl. J'ai hérité de DataGridViewColumn pour la nouvelle colonne et DataGridViewTextBoxCell pour la nouvelle cellule.Capturer premier caractère en entrant dans le mode d'édition - le contrôle d'édition personnalisé dans DataGridView

Avec un DataGridViewTextBoxCell normal, si vous appuyez sur une touche lorsque la cellule est mise au point, il va commencer le mode d'édition et le caractère que vous avez saisi apparaîtra dans la TextBoxEditingControl. Cependant, dans ma cellule héritée, aucune valeur n'est transmise sur keypress. (En fait, vous devez passer manuellement la valeur actuelle de la cellule dans InitializeEditingControl ou rien ne s'affichera.) Ainsi, le premier caractère que vous tapez (celui qui commence le mode d'édition) est perdu.

J'ai essayé OnKeyPress, OnKeyDown et OnKeyUp dans le DataGridViewCell mais ils ne sont jamais appelés. KeyEntersEditMode, cependant, semble être appelé, et seulement quand il vérifie contre une touche enfoncée, donc c'est peut-être un bon point de départ. Le problème devient alors comment traduire un KeyEventArgs à un char. Ceci est trivial pour l'alphabet et les nombres, mais comme tous les claviers ne sont pas créés égaux, la manipulation d'autres touches est compliquée et compliquée au mieux. S'il y a un convertisseur qui le fera automatiquement, s'il vous plaît éclairez-moi.

Est-ce que quelqu'un d'autre a rencontré ce problème ou trouvé une bonne solution de contournement?

Remarque: Ce problème s'applique lorsque EditMode est défini sur une variante de EditOnKeystroke. Définir à EditOnEnter est une solution de contournement valide pour mon projet, mais je voudrais également émuler le comportement par défaut du TextBoxEditingControl.

Répondre

1

Essayez de définir la KeyPreview du contrôle utilisateur sur true. Ensuite, vérifiez si la touche qui lance le processus d'édition déclenche le clavier même pour le contrôle de l'utilisateur. Si c'est le cas, vous pouvez simplement stocker et attribuer le caractère une fois que le contrôle de texte passe en mode d'édition.

1

Ma solution consiste à remplacer OnKeyPress sur le UserControl personnalisé.

protected override void OnKeyPress(KeyPressEventArgs e) 
{ 
    _textBox.Text = e.KeyChar.ToString(); 
    _textBox.SelectionStart = 1; 
    _textBox.SelectionLength = 0; 
    base.OnKeyPress(e); 
} 
+0

Le contrôle UserControl obtient-il la touche transmise à partir de DataGridView? –

0

Salut Aujourd'hui, j'eu le même problème. Ma solution est de remplacer KeyEntersEditMode dans CustomCell et d'y mettre un algorithme pour convertir ou pour déterminer si un caractère est valide pour passer au contrôle d'édition. Ensuite, je stocke cette valeur en tant que variable privée. Je remplace la méthode InitializeEditingControl et utilise ma valeur stockée comme valeur initiale pour le contrôle. Après l'avoir utilisé, je l'ai mis à zéro pour que plus tard rien ne l'utilise.


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; 
    } 

} 
0

Pour obtenir le premier caractère dans votre TextBox faire:

1) Ajouter "Imports System.Runtime.InteropServices" ou en utilisant si vous préférez C#

2) Ajouter à la cartographie SendMessage dans 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) Rediriger la clé de votre TextBox de 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) Il y a example on Microsoft page with the DataGridViewNumericUpDown here, téléchargez la source.

5) Terminé.

Questions connexes