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 en tant que:
private void Context_Delete(object sender, System.EventArgs e) { }
Comment puis-je obtenir la ligne sur laquelle se trouvait le menu contextuel avant le clic? L'objet sender
est System.Windows.Controls.MenuItem
, pas le DataGridRow
. Comment puis-je obtenir la DataGridRow
où le menu contextuel a été cliqué. (Je mets le DataGrid.ItemSource
dans le code derrière le fichier.)
Donc, en vous basant sur votre exemple de code, je suppose que vous liez votre DataGrid à un ObservableCollection d'objets dont vous liez les propriétés Site et Subject à DataGridColumns.
Pour l'essentiel, tout ce que vous avez à faire est de déterminer quel est l'élément lié au DataGridRow cliqué et de le supprimer de votre ObservableCollection. Voici un exemple de code pour vous aider à démarrer:
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);
}
Généralement, vous ne traitez pas de lignes (si vous le faites - réfléchissez bien aux raisons), vous utilisez plutôt le modèle de vue. Lorsque vous ouvrez le menu contextuel, votre élément est sélectionné et accessible via la propriété DataGrid.SelectedItem. Cependant, si vous avez vraiment besoin de DataGridRow - vous avez votre DataGrid.SelectedIndex et il y a beaucoup de réponses ici SO sur la façon d'obtenir la ligne. like Obtenir une ligne dans une grille de données
Pour développer le point de morincer ci-dessus avec un exemple, je me suis retrouvé avec 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
observableCollection auquel les lignes sont liées. Donc, conformément aux meilleures pratiques, je supprime simplement l'élément sélectionné de la collection et la liaison prend en charge l'interface utilisateur.
la réponse de dsfgsho a fonctionné pour moi, mais un clic droit sur une ligne de la grille ne la sélectionne pas automatiquement. Cela signifie que si votre objectif est ailleurs et que vous cliquez avec le bouton droit de la souris et sélectionnez un élément du menu contextuel, vous pouvez obtenir une exception en dehors de la plage définie pour item.SelectedCells [0], ou si vous avez sélectionné une ligne, puis cliquez avec le bouton droit rangée, vous pouvez obtenir des résultats inattendus.
J'ai traité cela en gérant "PreviewMouseRightButtonDown" sur la grille de données. Ici, je sélectionne explicitement une ligne lorsqu'elle est cliquée avec le bouton droit de la souris. J'oublie l'origine de ma classe UIHelpers (probablement ailleurs sur ce site - je l'utilisais pour résoudre les éléments de type glisser-déposer), mais cela devrait vous orienter dans la bonne direction si vous rencontrez ce problème. Ceci est 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();
}
}
UIHelper de Pete élémentaire provient probablement de:
http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop
Cet article répertorie un zip qui contient UIHelper.cs. Ce n'est pas mon code, donc pas de copier/coller ici.