9
votes

Dans une grille WPF, comment puis-je trouver la rangée et la colonne à l'emplacement de la souris?

J'ai une grille WPF avec des lignes et des colonnes, par exemple xxx

avec un gestionnaire pour Mousemove dans le fichier .CS , par exemple xxx

Je veux pouvoir trouver la ligne et la colonne de la grille la souris est terminée, est-ce possible?

[Note: Ceci est une version simplifiée du problème, il semble donc un peu étrange de le présenter de cette manière - cela fait partie de la glisser-déposer entre la fonctionnalité des grilles]


2 commentaires

Regardez dans la fonctionnalité Drag / Drop dans FLUIDKIT. Vous n'aurez pas à vous soucier de Hacky Shnit comme ça.


J'utilise déjà Fluidkit, que 'Mousemove' est vraiment "ONDropCompéduit" et la position de la souris est vraiment "Droppoint" - je veux pouvoir tomber dans des cellules spécifiques sur la table, que je n'ai pas réussi à travailler encore.


8 Réponses :


19
votes

J'espère que vous avez déjà trouvé une solution. J'ai rencontré le même problème et j'ai trouvé ce post sans réponse. Je pense donc que le prochain sera heureux de trouver cette solution:

private void OnMouseMove(object sender, MouseEventArgs e)
{
    var element = (UIElement)e.Source;

    int c = Grid.GetColumn(element);
    int r = Grid.GetRow(element);
}


2 commentaires

Cela ne fonctionne que si vous avez des uielements dans chaque cellule. Donc, ce n'est pas une réponse à la question posée.


@Greeneyedandy Pour résoudre ceci, vous pouvez simplement ajouter une bordure transparente à chaque rangée, avec une plage de colonnes qui correspond aux colonnes totales de cette rangée. Les tests de frappe obtiendront cette frontière et cela fonctionnera sur toutes les cellules, même si elles sont remplies ou non. Cela faciliterait également une caractéristique de surbrillance des lignes en modifiant l'arrière-plan de la bordure transparente de ladite rangée à une couleur, si vous le souhaitez.



5
votes

Ce que ce qui suit peut être fait (mais ne doit pas être utilisé sur des grandes grilles). Ce n'est que pour les lignes, mais une seconde boucle peut être appliquée aux colonnes ...

La réponse de Nicolas ne fonctionne que si la grille contient des uelements (dont la position dans la grille est déterminée - je suppose que cela causerait également des problèmes Si un élément couvre plusieurs rangées / colonnes). xxx


0 commentaires

0
votes

J'avais exactement votre même problème et j'utilise également Fluidkit. J'essaie de créer un concepteur de formulaire où vous pouvez faire glisser un contrôle d'une boîte à outils et déposez-le dans une cellule de grille. Voici comment j'ai résolu ce problème:

J'ai créé une grille avec deux rectangles factices dans la première rangée: xxx

Il ressemble comme suit:

grille

Notez que j'ai défini un droptargedvisor pour chacun de mes rectangles, la logique est maintenant comme suit:

  • Vous faites glisser / déposer un contrôle de la boîte à outils dans une cellule
  • Le OndropCompéduitd Méthode dans le Droptargedvisor Supprimez ensuite le rectangle où vous déposez le contrôle et obtiendrez ses coordonnées à partir du grid.row et grid.column propriétés ci-jointes.
  • Une fois que vous avez les coordonnées, vous pouvez définir ces propriétés connectées à votre contrôle glissé et l'ajouter à votre grille.

    Voici mon par défautDropTargedvisor.ondropCompletdvisor Méthode: xxx


0 commentaires

2
votes
protected override void OnMouseDown(MouseButtonEventArgs e)
{
    base.OnMouseDown(e);
    var hit = VisualTreeHelper.HitTest(this, e.GetPosition(this));
    if (hit == null) { return; }

    var grid = hit.VisualHit.Parent<Grid>();
    if (grid == null) { return; }

    var gridPosition = grid.GetColumnRow(e.GetPosition(grid));
    MessageBox.Show(string.Format("Grid location Row: {1} Column: {0}", gridPosition.X, gridPosition.Y));
}

0 commentaires

1
votes

espoir peut aider. Cela fonctionne bien pour mon application xxx


0 commentaires

0
votes

Pour un Telerik RadgridView, la meilleure approche si la grille ne contient pas d'éléments d'interface utilisateur consiste à utiliser des fichiers de l'UI dans une expression LINQ avec ISmouseOVER.

 private void myGridView_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
            {
                MyCustomClass myClass = null;

                var rows = this.myGridView.ChildrenOfType<GridViewRow>().Where(r => r.IsMouseOver == true);
                foreach (var row in rows)
                {
                    if (row is GridViewNewRow) break;
                    GridViewRow gvr = (GridViewRow)row;
                    myClass = (MyCustomClass)gvr.Item;
                } 
// do something with myClass here if we have found a row under mouse
}


0 commentaires

0
votes

La réponse d'André a une erreur mineure, car les coordonnées obtenues ne tiennent pas compte des en-têtes de ligne et de colonne dans la DataGrid. Au moins, c'était le cas lorsque j'ai mis en place la solution à Visual Basic.

Vous pouvez également modifier les exemples montrés pour compter pour un grand DataGrid. Il me semble que la limitation est basée sur la vue défilée, je montre donc deux implémentations de cette correction: p> xxx pré>

Notez que le ScrollViewer.horizontalOffset Propriété retourne une valeur dans Les pixels indépendants du périphérique, donc je me découvre simplement mon emplacement une fois avant de boucler dans les colonnes. P>

Notez que le ScrollViewer.verticalOffecTeCet Propriété renvoie le nombre d'éléments si Cancontentscroll = true. Donc, dans mon exemple, sur chaque boucle, j'ai compensé le compteur par la hauteur d'un élément (le DataGridrow). Si Cancontentscroll = False, il peut être traité comme dans le cas de la boucle d'index de colonne. P>

Je n'ai pas pu trouver des définitions de ligne dans le fichier Datagramrid pour .NET 4.0 dans Visual Basic, mais la fonction de support suivante Aide à l'obtention du dataGridrow: p> xxx pré>

et la fonction FindVisualChild dans Visual Basic: P>

Function FindVisualChild(Of childItem As DependencyObject)(ByVal p_obj As DependencyObject) As childItem
    For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(p_obj) - 1
        Dim child As DependencyObject = VisualTreeHelper.GetChild(p_obj, i)
        If child IsNot Nothing AndAlso TypeOf child Is childItem Then
            Return CType(child, childItem)
        Else
            Dim childOfChild As childItem = FindVisualChild(Of childItem)(child)
            If childOfChild IsNot Nothing Then
                Return childOfChild
            End If
        End If
    Next i
    Return Nothing
End Function


0 commentaires

1
votes

Remplacez la grille.columnDéfinitions en référence au composant de la grille

int GetColumn(double point)
{
   int index = 0;
   foreach(var column in Grid.ColumnDefinitions)
   {
      if(point > column.Offset && point < (column.Offset + column.ActualWidth))
          return index;
      index++;
   }
   return 0;
}


0 commentaires