![](/img/trans.png)
[英]Opened ContextMenu -> RightClick triggers LeftClickCommand in ViewModel
[英]Using MVVM, how can a ContextMenu ViewModel find the ViewModel that opened the ContextMenu?
我正在使用MVVM將視圖綁定到樹中的對象。 我有一個基類來實現我的樹中的項目,並且該基類具有ContextMenu屬性:
public IEnumerable<IMenuItem> ContextMenu
{
get
{
return m_ContextMenu;
}
protected set
{
if (m_ContextMenu != value)
{
m_ContextMenu = value;
NotifyPropertyChanged(m_ContextMenuArgs);
}
}
}
private IEnumerable<IMenuItem> m_ContextMenu = null;
static readonly PropertyChangedEventArgs m_ContextMenuArgs =
NotifyPropertyChangedHelper.CreateArgs<AbstractSolutionItem>(o => o.ContextMenu);
綁定到基類(以及所有派生類)的View實現了綁定到該屬性的ContextMenu:
<ContextMenu x:Name="contextMenu" ItemsSource="{Binding Path=(local:AbstractSolutionItem.ContextMenu)}"
IsEnabled="{Binding Path=(local:AbstractSolutionItem.ContextMenuEnabled)}"
ItemContainerStyle="{StaticResource contextMenuStyle}"/>
菜單中的每個項目都綁定到IMenuItem對象(菜單項的ViewModel)。 單擊菜單項時,它使用命令在基礎對象上執行命令。 一切都很好。
但是,一旦命令在IMenuItem類上執行,它有時需要獲取用戶右鍵單擊的對象的引用以顯示上下文菜單(或至少該對象的ViewModel)。 這是上下文菜單的重點。 我應該如何將樹項ViewModel的引用傳遞給MenuItem ViewModel? 請注意,某些上下文菜單由樹中的許多對象共享。
ContextMenu對象上有一個名為“PlacementTarget”的DP - 它將被設置為上下文菜單所附加的UI元素 - 您甚至可以將其用作綁定源,因此您可以通過CommandParameter將其傳遞給Command:
http://msdn.microsoft.com/en-us/library/system.windows.controls.contextmenu.placementtarget.aspx
編輯:在您的情況下,您需要PlacementTarget的VM,因此您的綁定可能看起來更像:
{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}
我通過在父控件(在View中擁有ContextMenu的控件)上處理ContextMenuOpening事件來解決這個問題。 我還向IMenuItem添加了一個Context屬性。 處理程序如下所示:
private void stackPanel_ContextMenuOpening(
object sender, ContextMenuEventArgs e)
{
StackPanel sp = sender as StackPanel;
if (sp != null)
{
// solutionItem is the "context"
ISolutionItem solutionItem =
sp.DataContext as ISolutionItem;
if (solutionItem != null)
{
IEnumerable<IMenuItem> items =
solutionItem.ContextMenu as IEnumerable<IMenuItem>;
if (items != null)
{
foreach (IMenuItem item in items)
{
// will automatically set all
// child menu items' context as well
item.Context = solutionItem;
}
}
else
{
e.Handled = true;
}
}
else
{
e.Handled = true;
}
}
else
{
e.Handled = true;
}
}
這利用了一次只能打開一個ContextMenu這一事實。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.