Получение контекстного меню сетки данных WPF Нажмите "Строка"
У меня есть DataGrid WPF
<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>
У меня есть обработчик события click:
private void Context_Delete(object sender, System.EventArgs e) { }
Как мне получить строку, на которой находилось контекстное меню до щелчка? Объектом sender
является System.Windows.Controls.MenuItem
, а не DataGridRow
. Как получить DataGridRow
, где было нажато контекстное меню. (Я установил DataGrid.ItemSource
в код за файлом.)
Ответы
Ответ 1
Итак, основываясь на вашем примере кода, я предполагаю, что вы привязываете свой DataGrid к ObservableCollection объектов, с которыми вы связываете свойства Site и subject с DataGridColumns.
По сути, все, что вам нужно сделать, - это выяснить, какой элемент привязан к щелчка DataGridRow и удалить его из вашего ObservableCollection. Вот пример кода, который вы можете запустить:
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);
}
Ответ 2
Как правило, вы не имеете дело со строками (если хотите - подумайте о причинах) - вместо этого вы работаете с моделью просмотра. Когда вы открываете контекстное меню, вы получаете свой элемент, поэтому его можно получить через свойство DataGrid.SelectedItem. Однако, если вам действительно нужен DataGridRow, у вас есть DataGrid.SelectedIndex, и здесь есть много ответов на SO о том, как получить строку. например Получить строку в datagrid
Ответ 3
Ответ dsfgsho работал у меня, но щелчок правой кнопкой мыши по строке сетки автоматически не выбирает его. Это означает, что если ваш фокус находится где-то в другом месте, и вы щелкните правой кнопкой мыши и выберите пункт контекстного меню, вы можете получить исключение вне диапазона на item.SelectedCells [0], или если у вас есть выбранная строка и щелкните правой кнопкой мыши на другом строка, вы можете получить неожиданные результаты.
Я справился с этим, обработав "PreviewMouseRightButtonDown" в Datagrid. Здесь я явно выбираю строку при щелчке правой кнопкой мыши. Я забыл, откуда пришел мой класс UIHelpers (возможно, в другом месте на этом сайте - я использовал его для разрешения элементов перетаскивания), но это должно указывать на вас в правильном направлении, если вы столкнулись с этой проблемой. Это расширение принятого ответа:
// 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();
}
}
Ответ 4
Чтобы расширить приведенную выше точку мора на примере, я закончил с более простым подходом...
private void MenuItem_OnClickRemoveSource(object sender, RoutedEventArgs e)
{
if (SourceDataGrid.SelectedItem == null) return; //safety first
_importViewModel.SourceList.Remove((SourceFileInfo)SourceDataGrid.SelectedItem);
}
В моем случае
_importViewModel.SourceList
- это ObservableCollection, к которому привязаны строки. Поэтому в соответствии с лучшими практиками я просто удаляю выбранный элемент из коллекции, и привязка заботится о пользовательском интерфейсе.
Ответ 5
Elemental Pete UIHelper, вероятно, вытекает из:
http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop
В этой статье указан Zip, содержащий UIHelper.cs.
Это не мой код, поэтому не копируйте и не вставляйте сюда.