简体   繁体   English

WPF-DataGrid上的上下文菜单

[英]WPF - context menu over DataGrid

My DataGrid is bound to a data source, which is a database. 我的DataGrid绑定到数据源即数据库。 When user right clicks somewhere over the DataGrid control, I'd like to be able to recognize over which column he or she did it. 当用户右键单击DataGrid控件上的某个位置时,我希望能够识别出他或她在哪个列上执行了该操作。 Scenario is as follows - if ContextMenu is opened over a column holding dates, then (for example) I would like to present him with options to filter out dates smaller, greater or equal to the date selected. 方案如下-如果在包含日期的列上打开了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 is a reference to the DataGrid , and I'd like it to be a reference to DataGridColumn. PlacementTarget是对DataGrid的引用,我希望它是对DataGridColumn的引用。

BindingProxy class: BindingProxy类:

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));
}

What you can do is hook up to the PreviewMouseUp event so you can look at the Source property of the Event that is raised. 您可以做的是连接到PreviewMouseUp事件,以便您查看引发的EventSource属性。

With the exception of direct events, WPF defines most routed events in pairs - one tunnelling and the other bubbling. 除了直接事件,WPF都是成对定义大多数路由事件-一种是隧道传输,另一种是冒泡。 The tunnelling event name always begins with 'Preview' and is raised first. 隧道事件名称始终以“预览”开头,并首先引发。 This gives parents the chance to see the event before it reaches the child. 这使父母有机会在事件到达孩子之前看到事件。 This is followed by the bubbling counterpart. 其次是冒泡的对象。 In most cases, you will handle only the bubbling one. 在大多数情况下,您将只处理冒泡的东西。 The Preview would be usually used to 预览通常用于

block the event (e.Handled = true) cause the parent to do something in advance to normal event handling. 阻止事件(e.Handled = true)会使父级提前执行正常事件处理。

eg if UI Tree = Button contains Grid contains Canvas contains Ellipse Clicking on the ellipse would result in (MouseDownButton is eaten up by Button and Click is raised instead.) 例如,如果UI Tree = Button包含Grid包含Canvas包含Ellipse,则在椭圆上单击将导致(MouseDownButton被Button吞噬,而Click被引发。)

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
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM