为什么Context for ContextMenuOpening对Canvas和UserControl的行为有所不同?

时间:2015-06-11 10:01:21

标签: c# wpf events contextmenu

我有一个简单的窗口:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:self="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="435" Width="613">
    <StackPanel>
        <Canvas Name="canvas">
            <self:Red />
        </Canvas>
        <UserControl Name="uc">
            <self:Blue />
        </UserControl>
    </StackPanel>
</Window>

RedBlue非常简单UserControls

<UserControl x:Class="WpfApplication1.Blue"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Rectangle Fill="Blue" Width="100" Height="100" />
    </Grid>
</UserControl>

我创建了一些ContextMenus:

public MainWindow()
{
    InitializeComponent();

    canvas.ContextMenu = new ContextMenu();
    canvas.ContextMenuOpening += (sender, e) =>
    {
        System.Diagnostics.Debug.WriteLine(e.Source.GetType());
    };

    uc.ContextMenu = new ContextMenu();
    uc.ContextMenuOpening += (sender, e) =>
    {
        System.Diagnostics.Debug.WriteLine(e.Source.GetType());
    };
}

如果我在Canvas打开上下文菜单,SourceRed,但如果我在UserControl上打开它,则Source为{ {1}}。
知道为什么吗? 我在MSDN上找到了这个:

  

ContextMenu本身是一个FrameworkElement派生类,但不会从作为源打开的上下文菜单中引发此事件。该事件来自&#34;拥有&#34;上下文菜单作为属性......

如果我理解正确,UserControl在第一种情况下应该Source,但它不是。

1 个答案:

答案 0 :(得分:1)

RoutedEventArgs.OriginalSource属性的MSDN文档中详细介绍了此行为:

  

各种元素和内容模型的来源调整因班级而异。调整事件源的每个类都会尝试预测哪个源对于大多数输入方案和类所针对的方案最有用,然后将该源设置为源。如果此源不是与您处理事件相关的源,请尝试检查OriginalSource,以查看它是否报告更合适的其他源。

这正是UserControl类所做的,它在其AdjustBranchSource()方法中修补了Source属性。

因此,正如引用文本暗示的那样,您可能正在寻找OriginalSource属性以使代码行为相似,在这两种情况下您都将获得对Rectangle的引用。