WPF - 数据网格上的上下文菜单
本文关键字:上下文 菜单 网格 数据 数据网 WPF | 更新日期: 2023-09-27 17:57:07
我的DataGrid
绑定到数据源,即数据库。当用户右键单击DataGrid
控件上的某处时,我希望能够识别他或她在哪一列上执行此操作。场景如下 - 如果在保存日期的列上打开ContextMenu
,那么(例如)我想向他提供选项来过滤掉更小、更大或等于所选日期的日期。
<DataGrid.Resources>
<Helpers:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
<DataGrid.ContextMenu>
<ContextMenu DataContext="{Binding Path=DataContext}">
<MenuItem Header="Cokolwiek" Command="{Binding Source={StaticResource proxy}, Path=Data.FK}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent.PlacementTarget.DataContext}"/>
</ContextMenu>
</DataGrid.ContextMenu>
PlacementTarget
是对DataGrid
的引用,我希望它是对DataGridColumn的引用。
绑定代理类:
public class BindingProxy : Freezable {
protected override Freezable CreateInstanceCore() {
return new BindingProxy();
}
public object Data {
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy), new UIPropertyMetadata(null));
}
您可以做的是挂接到PreviewMouseUp
事件,以便查看引发的Event
的Source
属性。
除直接事件外,WPF 成对定义大多数路由事件 - 一个隧道事件和另一个冒泡事件。隧道事件名称始终以"预览"开头,并首先引发。这使父母有机会在事件到达孩子之前看到事件。其次是冒泡的对应物。在大多数情况下,您只会处理冒泡的。预览通常用于
阻止事件(e.Handle = true)导致父级在 升级到正常事件处理。
例如,如果 UI 树 = 按钮包含网格包含画布包含椭圆单击椭圆将导致(鼠标向下按钮被按钮吃掉,而是单击被抬起。
private void OnPreviewMouseUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
var source = mouseButtonEventArgs.Source;
// Assuming the DataGridColumn's Template is just a TextBlock
// but depending on the Template which for sure should at least inherit from FrameworkElement to have the Parent property.
var textBlock = source as TextBlock;
// Not a good check to know if it is a holding dates but it should give you the idea on what to do
if (textBlock != null)
{
var dataGridColumn = textBlock.Parent as DataGridColumn;
if (dataGridColumn != null)
{
if ((string) dataGridColumn.Header == "Holding Dates")
{
// Show context menu for holding dates
}
}
}
// Other stuff
else if (somethingElse)
{
// Show context menu for other stuff
}
}