如何为 ListBoxItems 创建动态上下文菜单?

Posted

技术标签:

【中文标题】如何为 ListBoxItems 创建动态上下文菜单?【英文标题】:How do I create a dynamic context menu for ListBoxItems? 【发布时间】:2017-02-06 15:56:34 【问题描述】:

我的风格似乎行不通。尽管 Snoop 告诉我 DataContextListBoxItem 是正确的,但没有任何显示。如果 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 的任何绑定错误或警告

为什么没有设置上下文菜单?

【问题讨论】:

哦,等等——对不起,我刚刚略过了你的问题。我认为您在这里可能遇到的唯一问题只是菜单项样式的定义位置。它在内容中,将被忽略。试着把它放在&lt;ContextMenu&gt;&lt;ContextMenu.ItemContainerStyle&gt;&lt;Style TargetType="MenuItem" .../&gt; ... 上下文菜单未连接到其“父级”的可视化树。这意味着他们不会继承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 中为上下文菜单动态选择菜单项的正确方法是啥?

我们如何为异步 .net 方法创建调用上下文?

如何为贝宝上下文快速结帐创建反应组件?

如何为paypal上下文快速结账创建反应组件?

如何为特定页面创建父组件(以便能够在父级中添加反应上下文)?

如何为 Handsontable 创建动态列?