Фреймворк фактически отслеживает это значение в свойстве PopupControlService.Owner, но это внутренний класс.Если вы хотите использовать недокументированные функции, вы можете перебрать свойства в ContextMenu и извлечь его:
private static object GetOwner(ContextMenu menu)
{
var prop = menu.GetLocalValueEnumerator();
while (prop.MoveNext())
{
if (prop.Current.Property.Name == "Owner" &&
prop.Current.Property.OwnerType.Name == "PopupControlService")
{
return prop.Current.Value;
}
}
return null;
}
Другой подход заключается в том, что ContextMenuService.ContextMenuOpeningEvent будет вызванопо гиперссылке, чтобы вы могли взять параметр отправителя и поместить его в свое собственное присоединенное свойство.Примерно так:
public class ContextMenuOwnerTracker
{
private static bool isInitialized;
public static void Initialize()
{
if (!isInitialized)
{
isInitialized = true;
EventManager.RegisterClassHandler(typeof(ContentElement),
ContextMenuService.ContextMenuOpeningEvent,
new ContextMenuEventHandler(OnContextMenuOpening));
EventManager.RegisterClassHandler(typeof(ContentElement),
ContextMenuService.ContextMenuClosingEvent,
new ContextMenuEventHandler(OnContextMenuClosing));
}
}
private static void OnContextMenuOpening
(object sender, ContextMenuEventArgs args)
{
var menu = ContextMenuService.GetContextMenu((DependencyObject)sender);
if (menu != null)
{
SetOwner(menu, sender);
}
}
private static void OnContextMenuClosing
(object sender, ContextMenuEventArgs args)
{
var menu = ContextMenuService.GetContextMenu((DependencyObject)sender);
if (menu != null)
{
ClearOwner(menu);
}
}
private static readonly DependencyPropertyKey OwnerKey =
DependencyProperty.RegisterAttachedReadOnly(
"Owner",
typeof(object),
typeof(ContextMenuOwnerTracker),
new PropertyMetadata(null));
public static readonly DependencyProperty OwnerProperty =
OwnerKey.DependencyProperty;
public static object GetOwner(ContextMenu element)
{
return element.GetValue(OwnerProperty);
}
private static void SetOwner(ContextMenu element, object value)
{
element.SetValue(OwnerKey, value);
}
private static void ClearOwner(ContextMenu element)
{
element.ClearValue(OwnerKey);
}
}
Обратите внимание, что может быть несколько ContentElements со свойствами ContextMenu, и это фактически установит Владельца для всех из них, даже если это имеет значение только для того, который фактически отображается.
Чтобы получить значение для определенного элемента MenuItem, вам придется пройтись по дереву или использовать привязку с {RelativeSource AncestorType=ContextMenu}
.Вы также можете пометить свойство Owner, унаследованное, чтобы оно автоматически распространялось на MenuItems.
Если вы прикрепляете контекстное меню на более высоком уровне, чем Гиперссылка, вы можете использовать OriginalSource вместо отправителя, но это обычно дает вам Run, поэтому вам придется идти вверх по дереву, чтобы найти Hyperlink,