Menu contextuel de la grille de données du FPF cliquez sur la ligne

j'ai un WPF DataGrid

<DataGrid AutoGenerateColumns="False"  Name="dataGrid1"  IsReadOnly="True" >
<DataGrid.Columns>
    <DataGridTextColumn Header="Site" Binding="{Binding Site}" Width="150" />
    <DataGridTextColumn Header="Subject" Binding="{Binding Subject}" Width="310" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Delete" Click="Context_Delete">
            <MenuItem.Icon>
                <Image Width="12" Height="12" Source="Images/Delete.png" />
            </MenuItem.Icon>
        </MenuItem>
    </ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>

j'ai le gestionnaire d'événements click:

private void Context_Delete(object sender, System.EventArgs e)  { }

Comment puis-je obtenir la ligne sur laquelle le Menu contextuel était avant le clic? sender l'objet est System.Windows.Controls.MenuItem, pas DataGridRow. Comment puis-je obtenir le DataGridRow où le Menu Contextuel a été cliqué. (j'ai mis le DataGrid.ItemSource dans le code derrière le fichier.)

16
demandé sur svick 2013-05-30 00:10:57

5 réponses

donc basé sur votre code d'exemple, je présume que vous liez votre DataGrid à une collection observable D'objets dont vous liez le Site de propriétés et soumis aux DataGridColumns.

essentiellement, tout ce que vous devez faire est de comprendre ce que l'élément lié au DataGridRow cliqué est et de supprimer cela de votre collection observable. Voici un exemple de code pour commencer:

private void Context_Delete(object sender, RoutedEventArgs e)
{
    //Get the clicked MenuItem
    var menuItem = (MenuItem)sender;

    //Get the ContextMenu to which the menuItem belongs
    var contextMenu = (ContextMenu)menuItem.Parent;

    //Find the placementTarget
    var item = (DataGrid)contextMenu.PlacementTarget;

    //Get the underlying item, that you cast to your object that is bound
    //to the DataGrid (and has subject and state as property)
    var toDeleteFromBindedList = (YourObject)item.SelectedCells[0].Item;

    //Remove the toDeleteFromBindedList object from your ObservableCollection
    yourObservableCollection.Remove(toDeleteFromBindedList);
}
27
répondu dsfgsho 2013-05-29 21:40:29

généralement, vous ne traitez pas avec les lignes (si vous le faites - pensez à nouveau aux raisons) - à la place vous travaillez avec le modèle view. Lorsque vous ouvrez le menu contextuel, vous obtenez votre élément sélectionné, de sorte qu'il peut être accédé via le DataGrid.Propriété SelectedItem. Cependant, si vous avez vraiment besoin de DataGridRow - vous avez votre DataGrid.SelectedIndex et il ya beaucoup de réponses ici sur donc sur la façon d'obtenir la rangée. comme Obtenir une ligne dans la grille de données

6
répondu morincer 2017-05-23 11:54:37

pour étendre le point de morincer ci-dessus avec un exemple, j'ai fini par une approche plus simple...

 private void MenuItem_OnClickRemoveSource(object sender, RoutedEventArgs e)
 {
     if (SourceDataGrid.SelectedItem == null) return;  //safety first

     _importViewModel.SourceList.Remove((SourceFileInfo)SourceDataGrid.SelectedItem);
 }

Dans mon cas, le

_importViewModel.SourceList 

est l'ObservableCollection les lignes sont liés. Ainsi, selon les meilleures pratiques, I simple Supprimer l'élément sélectionné de la collecte et la liaison prend soin de L'UI.

3
répondu ebol2000 2014-12-18 17:22:39

la réponse de dsfgsho a fonctionné pour moi, mais le clic droit sur une ligne de grille ne le sélectionne pas automatiquement. Cela signifie que si votre cible est ailleurs et vous cliquez à droite et sélectionnez un élément de menu contextuel, vous pouvez obtenir une gamme d'exception sur le point.SelectedCells[0], ou si vous avez une rangée sélectionnée et cliquez avec le bouton droit de la souris sur une autre rangée, vous pouvez obtenir des résultats inattendus.

j'ai géré cela en manipulant "PreviewMouseRightButtonDown" sur le Datagrid. Ici je sélectionne explicitement une ligne lorsqu'il est cliqué avec le bouton droit. J'oublie d'où vient ma classe UIHelpers (probablement ailleurs sur ce site - je l'utilisais pour résoudre drag & drop items), mais cela devrait vous pointer dans la bonne direction si vous rencontrez ce problème. Il s'agit d'une extension de la réponse acceptée:

// handle right mouse click to select the correct item for context menu usage
    private void myDataGrid_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        //find the clicked row
        DataGridRow row = UIHelpers.TryFindFromPoint<DataGridRow>((UIElement) sender, e.GetPosition(myDataGrid));
        if (row == null)
        {
            Debug.WriteLine("Row is null");
            return;
        }
        else
        {
            Debug.WriteLine("Grid Row Index is " + row.GetIndex().ToString());
            (sender as DataGrid).SelectedIndex = row.GetIndex();
        }
    }
2
répondu Elemental Pete 2015-05-15 15:07:19

élément L'UIHelper de Pete provient probablement de:

http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop

cet Article répertorie une zone qui contient UIHelper.cs. Ce n'est pas mon Code, donc pas de copier/coller ici.

0
répondu Patrick Artner 2017-08-22 06:49:30