2010-10-06 3 views
0

Woot, premier message de dépassement de pile! On m'a demandé de travailler sur une application de bureau pour améliorer le processus d'inventaire de mon entreprise. Je me suis amusé avec WPF à l'école et je me suis dit que je commencerais là. Après avoir fait des recherches, j'ai appris à connaître MVVM, à mettre en place un design et à aller de l'avant. Finalement, je suis coincé et je cherche de l'aide et aussi une vérification de santé mentale pour voir si je suis sur le bon chemin.Définir le WPG DataGridCell sélectionné pour être focalisé et éditable lors de l'événement

J'ai un DataGrid à une seule colonne lié à une collection observable. Les utilisateurs de l'application utilisent un pistolet d'analyse pour entrer des valeurs. Une valeur potentielle que j'attrape dans mon objet de modèle "Cell" est une valeur "MoveNextColumn". Cela déclenche un événement personnalisé dans mon modèle qui est géré dans le modèle View. Le gestionnaire est supposé simuler des entrées vides pour toutes les lignes restantes dans cette colonne, mettre le focus sur la dernière ligne et attendre l'entrée avant de continuer. Voici donc ce que j'ai jusqu'à présent:

private void dummyCell_MoveToNextColumn(object sender, RoutedEventArgs e) { 
     e.Handled = true; 

     // Cell is the model object containing the parsing rules and raising events 
     var lSender = sender as Cell; 
     var gridItems = ViewGridReference.Items; 
     var lastItem = gridItems[gridItems.Count - 1]; 

     if (lSender == lastItem) { 
      // We are at the bottom of the column 
      // Move the program on to the next column 
      CurrentColumn++; 
      OnPropertyChanged("ItemPositions"); 
     } else { 
      // Simulate "empty position" input for this cell and all cells down the column 
      // Cells are validating themselves as the simulation progresses 
      foreach (Cell item in ViewGridReference.Items) { 
       item.ActualItemCode = string.Empty; 
      } 

      // ViewGridReference is a reference to my DataGrid set from the view 
      ViewGridReference.Focus(); 

      ViewGridReference.SelectedIndex = gridItems.Count - 1; 
      ViewGridReference.CurrentCell = new DataGridCellInfo(lastItem, ViewGridReference.Columns[0]); 
      ((DataGridCell)ViewGridReference.SelectedItem).Focus();    
     }         
    } 

Tout cela semble fonctionner comme prévu: toutes les lignes reçoivent l'entrée en blanc et sont validés (j'utilise les propriétés de couleur dans la cellule à laquelle la vue se fixe pour signifier la validité de l'entrée). Malheureusement, bien que l'accent soit mis sur la dernière ligne comme souhaité, elle ne peut pas être modifiée et l'utilisateur ne peut pas envoyer une autre valeur "MoveNextColumn" qui pourrait activer le programme. Le but ici est de minimiser toute interaction au clavier. Tout devrait être fait avec des pistolets de balayage et des codes à barres.

Des idées sur la façon de rendre la cellule sélectionnée modifiable après l'exécution de ce code? Tout commentaire "hé, votre conception craint" serait cool aussi. Ceci est nouveau pour moi et je suis ouvert à constructive critique.

Répondre

0

J'ai fait quelques progrès avec ceci. La grille entière a été laissée à un état non modifiable dans le code ci-dessus. Cela laisse maintenant l'accent sur la dernière cellule de ma colonne et me permet de soumettre une entrée avec le pistolet de balayage.

Cela semble fonctionner, mais j'apprécierais quand même de recevoir des commentaires sur la question de savoir s'il existe une meilleure solution.

private void dummyCell_MoveToNextColumn(object sender, RoutedEventArgs e) { 
     e.Handled = true; 

     // Cell is the model object containing the parsing rules and raising events 
     var lSender = sender as Cell; 
     var gridItems = ViewGridReference.Items; 
     var lastItem = gridItems[gridItems.Count - 1]; 

     if (lSender == lastItem) { 
      // We are at the bottom of the column 
      // Move the program on to the next column 
      CurrentColumn++; 
      OnPropertyChanged("ItemPositions"); 
     } else { 
      // Simulate "empty position" input for this cell and all cells down the column 
      // Cells are validating themselves as the simulation progresses 

      foreach (Cell item in ViewGridReference.Items) { 
       item.ActualItemCode = string.Empty; 
      } 

      ViewGridReference.SelectedIndex = gridItems.Count - 1; 
      ViewGridReference.CurrentCell = new DataGridCellInfo(lastItem, ViewGridReference.Columns[0]); 

      (ViewGridReference.ItemsSource as ListCollectionView).EditItem(ViewGridReference.SelectedItem); 
      ((DataGridCell)ViewGridReference.SelectedItem).Focus();           
     }         
    } 

Mise à jour 12/2/2010

Hey, il y a une importante mise à jour à ce sujet. La première chose à noter est que l'entrée de texte est faite avec un pistolet de balayage dans mon scénario, donc les touches 'Entrée' sont envoyées à chaque tir du déclencheur. Il abat tous les caractères suivis de la touche Entrée en même temps.

WPF voit cette entrée et souhaite définir le focus sur DataGridCell directement sous la cellule dans laquelle l'entrée Entrée clé a été reçue. Le code ci-dessus définit le focus sur la dernière cellule, mais l'événement de clé Enter se déclenche toujours et est géré par DataGrid après l'exécution de ce code. L'effet est que le focus est réinitialisé à la cellule suivante, pas la dernière cellule comme je le veux.

Alors j'ai besoin soit de comprendre comment manger la touche Entrée pour ce scan, ou j'ai besoin de casser comment WPF gère les touches Entrée. La dernière ligne là-bas jette une exception. Nous essayons d'utiliser une classe Model (Class.cs) en tant que DataGridCell, et il n'y a rien pour gérer cette distribution. À cause de cela, la méthode Focus() essaie de fonctionner sur un objet nul et nous obtenons une exception NullReferenceException. Cela me déroutait vraiment parce que Visual Studio 2010 cassait parfois pour m'avertir à ce sujet, mais parfois non. Cependant, si j'exécute l'exécutable en dehors de Visual Studio, cela fonctionne très bien. En effet, les exceptions non gérées et non fatales sont ignorées et le comportement de la touche Entrée ne fonctionne pas normalement.

Donc, cela fonctionne, mais d'une manière assez grossière. J'ai soit besoin de comprendre comment faire une manipulation unique de la touche Entrée et remplacer le gestionnaire WPF par défaut, ou laissez simplement comme il est et grimace.

Questions connexes