如何为 ListBoxItems 创建动态上下文菜单?
Posted
技术标签:
【中文标题】如何为 ListBoxItems 创建动态上下文菜单?【英文标题】:How do I create a dynamic context menu for ListBoxItems? 【发布时间】:2017-02-06 15:56:34 【问题描述】:我的风格似乎行不通。尽管 Snoop 告诉我 DataContext
的 ListBoxItem
是正确的,但没有任何显示。如果 Commands
的绑定有问题,我希望看到一个空的上下文菜单。
风格:
<ContextMenu x:Key="CommandsContextMenu" ItemsSource="Binding Commands">
<Style TargetType="MenuItem">
<Setter Property="Header" Value="Binding Name"/>
</Style>
</ContextMenu>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu" Value="StaticResource CommandsContextMenu" />
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<Binding Path="DataContext.HasCommands" />
</DataTrigger.Binding>
</DataTrigger>
</Style.Triggers>
</Style>
窥探数据上下文:
显示 ContextMenu 属性的 snoop 属性甚至没有设置。
这里的想法是,在不知道任何类型的情况下,我可以有一个列表框项样式,如果它绑定到的东西有一个名为 HasCommands 的属性,并且它被设置为 true,那么它将设置一个上下文该列表框项上的菜单,绑定到 Commands 属性。
我没有收到来自PresentationTraceSources.DataBindingSource
的任何绑定错误或警告
为什么没有设置上下文菜单?
【问题讨论】:
哦,等等——对不起,我刚刚略过了你的问题。我认为您在这里可能遇到的唯一问题只是菜单项样式的定义位置。它在内容中,将被忽略。试着把它放在<ContextMenu><ContextMenu.ItemContainerStyle><Style TargetType="MenuItem" .../> ...
上下文菜单未连接到其“父级”的可视化树。这意味着他们不会继承DataContext
。有关解决此问题的一些方法,请参阅此问题。 ***.com/questions/15033522/…
我在这里看到的一个潜在问题是您的ContextMenu
被定义为资源。默认情况下,只创建一个实例,然后在每次从字典中提取时返回,导致这个实例被设置为多个元素的上下文菜单,我认为这可能是你的问题的原因。尝试在其上设置x:Shared="False"
,以确保每次从字典中获取资源时都会创建一个新实例。此外,@BradleyUffner 的评论很有用,可能会成为您遇到的下一个问题。
在我看来,所有 cmets 都是会阻止菜单包含项目或具有不同项目的东西,而不是会阻止为任何一个设置上下文菜单的东西他们。不过,我会试一试
@EdPlunkett 我以为可以工作,但没有=(
【参考方案1】:
事实证明,问题出在使用从 ListBox
继承的东西
参考这里是我定义的类:
// adapted from http://***.com/questions/3350187/wpf-c-rearrange-items-in-listbox-via-drag-and-drop
// which was probably adapted from http://wpftutorial.net/DragAndDrop.html
type DragDropListBox() as self =
inherit ListBox()
从那里只挂钩以下内容
self.PreviewMouseLeftButtonUp self.PreviewMouseMove 覆盖 x.OnItemsSourceChanged在初始化过程中,它覆盖 ItemContainerStyle,如下所示:
事实证明,问题出在使用从 ListBox
继承的东西
作为参考,这是我班上的佼佼者:
// adapted from http://***.com/questions/3350187/wpf-c-rearrange-items-in-listbox-via-drag-and-drop
// which was probably adapted from http://wpftutorial.net/DragAndDrop.html
type DragDropListBox() as self =
inherit ListBox()
从那里只挂钩以下内容
self.PreviewMouseLeftButtonUp self.PreviewMouseMove 覆盖 x.OnItemsSourceChanged在初始化过程中,它覆盖 ItemContainerStyle,如下所示:
do
self.PreviewMouseLeftButtonUp.Add listBoxPreviewMouseLeftButtonUp
//self.PreviewMouseLeftButtonDown.Add listBoxPreviewMouseMove //.AddHandler (MouseButtonEventHandler previewMouseMove)
self.PreviewMouseMove.Add listBoxPreviewMouseMove
let style =
let s = Style(typeof<ListBoxItem>)
s.Setters.Add (Setter(ListBoxItem.AllowDropProperty, true))
s.Setters.Add (EventSetter(ListBoxItem.PreviewMouseLeftButtonDownEvent, MouseButtonEventHandler listBoxPreviewMouseLeftButtonDown))
s.Setters.Add (EventSetter(ListBoxItem.DropEvent, DragEventHandler listBoxItemDrop))
s
self.ItemContainerStyle <- style
现在我必须弄清楚你是否可以将两种样式添加在一起。
【讨论】:
以上是关于如何为 ListBoxItems 创建动态上下文菜单?的主要内容,如果未能解决你的问题,请参考以下文章
在 WinForms 中为上下文菜单动态选择菜单项的正确方法是啥?