2015-03-17 1 views
3

figure Can not pourquoi il n'est pas, voici l'exemple de code:événement KeyUp ne tirait pas sur DataGrid

public Form1() 
     { 
      InitializeComponent(); 
      //Create DataGrid 
      DataGrid dg = new DataGrid(); 
      dg.Parent = this; 
      dg.Location = new Point(10, 10); 
      dg.Size = new System.Drawing.Size(300, 200); 
      //Create list of people 
      List<Person> people = MethodThatFetchesPeople(); 
      //Bind list 
      BindingList<Person> bl_people = new BindingList<Person>(people); 
      dg.DataSource = bl_people; 
      //Format grid 
      dg.TableStyles.Clear(); 
      DataGridTableStyle dgts = new DataGridTableStyle(); 
      dgts.MappingName = bl_people.GetType().Name; 
      dgts.ReadOnly = true; 
      DataGridTextBoxColumn col_name = new DataGridTextBoxColumn(); 
      col_name.MappingName = "Name"; 
      col_name.HeaderText = "Name"; 
      dgts.GridColumnStyles.Add(col_name); 
      DataGridTextBoxColumn col_height = new DataGridTextBoxColumn(); 
      col_height.MappingName = "Height"; 
      col_height.HeaderText = "Height (cm)"; 
      dgts.GridColumnStyles.Add(col_height); 
      dg.TableStyles.Add(dgts); 
      //Subscribe events 
      col_name.TextBox.KeyDown += new KeyEventHandler(TextBox_KeyDown); 
      col_name.TextBox.KeyUp += new KeyEventHandler(TextBox_KeyUp); 
     } 

Les méthodes de gestion des événements:

 void TextBox_KeyUp(object sender, KeyEventArgs e) 
     { 
      //Do something on keyup 
      Debug.WriteLine("Keyup!"); 
     } 

     void TextBox_KeyDown(object sender, KeyEventArgs e) 
     { 
      //Do something on keydown 
      Debug.WriteLine("Keydown!"); 
     } 
    } 

Après avoir appuyé sur une valeur de la Nom colonne, que DataGridTextBoxColumn obtient le focus. Puis chaque fois que j'appuie sur une touche du KeyDown événement est congédié, mais rien ne se passe pour l'événement KeyUp, même lorsque l'événement KeyDown n'est pas souscrit.
J'ai vraiment juste besoin de l'événement KeyUp, le KeyDown ne correspond pas à mon objectif. Et je ne peux pas passer à l'DataGridView que ce code sera utilisé avec le cadre compact :(
Comment puis-je résoudre ce problème?

+0

Ce problème se produit également sur le plein.Net Framework, je l'ai juste collé sur un nouveau projet et essayé avec une classe Person générique: 'public class Personne { public string Nom {get; ensemble; } public int Hauteur {get; ensemble; } public int Enfants {get; ensemble; } } ' –

+0

Je suppose que vous devrez sous-classer DataGridTextBoxColumn afin que vous puissiez fournir votre propre classe Textbox sous-classée en tant que contrôle d'hôte afin que vous puissiez vous connecter à OnKeyDown. – tcarvin

+0

Jetez un oeil à cette bibliothèque de l'interface utilisateur https://b2kui.codeplex.com/, elle implémente un datagird éditable pour CF et a quelques classes qui servent de solution de contournement pour des problèmes similaires avec la gestion des événements de presse de touche. Divulgation complète: je maintiens ce projet – bit2know

Répondre

2

J'ai vu cela se produire spécifiquement sur Windows Forms/application de bureau, mais l'affichage ici au cas où il est également vrai sur le contrôle mobile. DataGrid

a l'habitude d'avaler certains événements clavier, les traite en interne (je crois qu'ils sont traitées par les cellules individuelles de la grille) et elles ne "passeront pas" à d'autres contrôles car l'événement a déjà été consommé.

Il y a deux façons de procéder. Fondamentalement, vous devez configurer le formulaire pour intercepter l'événement avant qu'il ne frappe le DataGrid, puis pré-traiter et décider si vous souhaitez également passer l'événement à DataGrid.

Pour créer un "Filtre universel" dans votre application, procédez comme suit. Vous le feriez si vous suivez un modèle répartiteur et potentiellement besoin d'acheminer la course clé pour l'un des nombreux contrôles différents:

Dans le constructeur de votre formulaire:

this.KeyPreview = true; 
Application.AddMessageFilter(this); 

Remplacer cette méthode dans votre formulaire. Si cette méthode renvoie "true", l'événement sera consommé et ne sera pas distribué à d'autres contrôles. Si cette méthode renvoie "false", l'événement se répercutera normalement sur tous les contrôles.

// This is the ONLY way to prevent buttons, checkboxes, and datagrids from processing the UP and DOWN arrows 
    const int WM_KEYDOWN  = 0x100; 
    const int WM_KEYUP   = 0x101; 
    public bool PreFilterMessage(ref Message m) 
    { 
     try 
     { 

      if (m.Msg == WM_KEYDOWN) 
       // handle event here and return true 
      else if (m.Msg == WM_KEYUP) 
       // handle event here and return true 
      } 
     } 
     catch 
     { 
      return false; 
     } 

    return false; 
    } 

j'ai écrit/compris tout ça il y a environ 10 ans, alors peut-être il y a d'autres/de meilleures façons de faire, mais cela a fonctionné pour moi et je ne pas créer des implémentations personnalisées de tous les contrôles pour faire ça marche.


Une autre technique trouvée dans un article MSDN. Il est écrit pour VB, mais devrait se traduire assez facilement à C#:

https://support2.microsoft.com/default.aspx?scid=kb;en-us;320583&Product=vbNET

Le principe de base est de sous-classe le DataGrid ici et remplacer la méthode ProcessCmdKey.

+0

Merci pour la réponse, l'implémentation 'IMessageFilter' sur le formulaire est une solution de contournement, mais la deuxième solution que vous avez mentionnée ne fonctionne pas, car la méthode' ProccessCmdKey' n'attrape pas wm_keyup, seulement wm_keydown –

+0

Pour être honnête, je n'ai pas testé la deuxième solution, c'était juste quelque chose que je tombais par hasard et que je voulais inclure au cas où cela serait utile Je pense que la prémisse de la seconde solution est saine mais vous pouvez besoin de sous-classer un élément différent tel que la colonne de la grille ou la cellule pour capturer le KeyUp. – user700390

0

Ce MSDN Article suggère l'événement du clavier dans la manipulation FC ne sont pas facile, mais il peut offrir une solution. Je ne l'ai pas lu tout.

+0

Merci pour votre réponse, mais cet article semble destiné à ceux qui veulent explorer les aspects natifs de Windows CE ... dans ce cas, je veux juste faire l'événement keyup de tirer, et je peux Ne pas vraiment comprendre pourquoi il ne fonctionne pas :( –