Время от времени я хотел бы показывать контекстное меню при нажатии на ячейку в DataGrid. Я создаю ContextMenu программно, а затем показываю его с помощью ContextMenu.IsOpen = true. В приведенном ниже примере он работает при нажатии внутри панели «Сетка», но это не означает, что щелчок по ячейке (UIElement внутри ячейки) DataGrid.WPF DataGrid: Показать динамическое контекстное меню по левому щелчку
В чем разница? Что мне нужно сделать, чтобы заставить его работать и с DataGridCell?
Здесь представлена демо-версия, первая XAML и ниже кода позади.
<Window x:Class="WpfApplication7_delete_me.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication7_delete_me"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid MouseDown="Grid_MouseDown" Background="Beige">
<DataGrid x:Name="dataGrid" HorizontalAlignment="Left" VerticalAlignment="Top" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" MouseDown="TextBlock_MouseDown" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
вот код позади:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication7_delete_me {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
Person p1 = new Person(); p1.Name = "abc";
Person p2 = new Person(); p2.Name = "1q23";
List<Person> l = new List<Person>() { p1, p2 };
dataGrid.ItemsSource = l;
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e) {
ContextMenu cm = new ContextMenu();
MenuItem mi = new MenuItem();
mi.Header = "hallo";
cm.Items.Add(mi);
cm.IsOpen = true;
}
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) {
ContextMenu cm = new ContextMenu();
MenuItem mi = new MenuItem();
mi.Header = "hallo";
cm.Items.Add(mi);
cm.IsOpen = true;
}
}
class Person {
public string Name { get; set; }
}
}
Через некоторое время я нашел два решения:
1) Это работает при использовании PreviewMouseDown вместо MouseDown.
2) Использование: Dispatcher.BeginInvoke(new Action(() => { c.IsOpen = true; }), null);
Но почему установка IsOpen внутри MouseDown случае не работает?
у вас проверены ответы – AnjumSKhan
У меня все еще нет ответа. Я только что нашел обходное решение. Вопрос в том, почему MouseDown для DataGrid не работает, пока он работает, например, на панели Grid. –
То, что я упомянул, является стандартным способом отображения динамического контроля меню msdn – AnjumSKhan