按需填充上下文菜单

Posted

技术标签:

【中文标题】按需填充上下文菜单【英文标题】:Filling Contextmenu on demand 【发布时间】:2012-10-03 13:05:29 【问题描述】:

我有一个实体视图模型。由于 UI 中可以有许多实体,因此我使用了 DataTemplate 来表示实体视图模型。容器控件的 ItemTemplate 属性使用此数据模板来呈现实体。 请注意,这不是传统的 ListView/ListBox 控件。它是一个图形控件,其边和节点由数据模板表示。 这就是说,每个节点都是不同的类型,当用户右键单击时,模板的上下文菜单将绑定到视图模型提供的集合。以下代码工作正常:

<DataTemplate DataType="x:Type model:Person">
        <Border Style="StaticResource NodeBorderStyle" MinWidth="200">

            <Border.ContextMenu>
                <ContextMenu ItemsSource="Binding ContextOperations">
                    <ContextMenu.ItemContainerStyle>
                        <Style TargetType="MenuItem">                             
                            <Setter Property="Command" Value="Binding PlacementTarget.DataContext.HandleContextOperationCommand, RelativeSource=RelativeSource AncestorType=ContextMenu"/>
                            <Setter Property="CommandParameter" Value="Binding RelativeSource=x:Static RelativeSource.Self, Path=Header"/>
                        </Style>
                    </ContextMenu.ItemContainerStyle>
                </ContextMenu>
            </Border.ContextMenu>
....................
  </Border >
</DataTemplate>

这有一个限制,在初始化视图模型时必须填充 ContextOperations(一个 ObservableCollection)属性。 可能有许多节点,因此在加载时为所有节点存储上下文菜单项可能是一个巨大的内存问题。 我希望当用户右键单击实体(模板)时,视图模型的 ContextOperations 属性被填充,然后上下文菜单被渲染。 此 DataTemplate 保存在资源文件中。 任何指导将不胜感激。 谢谢。

问候,

【问题讨论】:

【参考方案1】:

处理数据模板边框上的 MouseRightButtonUp 事件并像这样创建上下文菜单运行时:

private void borderMouseRightButtonUp(object sender, MouseButtonEventArgs e)

    OpenContextMenu(sender as ComboBox);



private void OpenContextMenu(FrameworkElement element)

    if (element.ContextMenu == null)
    
        ContextMenu c = new ContextMenu();
        //Load the ContextOperations from ViewModel 
        //based on the Framework element datacontext
        ContextOperations.ToList().ForEach(co => c.Items.Add(new MenuItem()
         
           //Create your menu item
        ));

        element.ContextMenu = c;

    

    element.ContextMenu.PlacementTarget = element;
    element.ContextMenu.IsOpen = true;


并从 XAML 中删除 contextmenu 的定义。

【讨论】:

感谢您的回答,我不确定,但这是否符合 MVVM 标准?据我所知,这不会破坏单元可测试性,因为在单元测试期间我所关心的只是 OC 是否被填充。你能告诉我把这段代码放在哪里吗? 我的猜测是 [mvvm] 标签表明应该避免后面的代码。但是,这可以包装在一个行为中,然后可以使用将行为绑定到视图模型的数据来执行“从 ViewModel 加载 ContextOperations”。 抱歉,我误解了您对 MVVM 的严格需求!我会考虑一个符合 MVVM 的解决方案。 谢谢马丁!行为是指我必须编写行为类的附加行为或交互行为?我的意思是这样的:codeproject.com/Articles/35721/… 我猜,现在我知道该怎么做了。谢谢你马丁。 Michele 的解决方案可以包装成如下内容:codeproject.com/Articles/35721/… 在上面的文章中,还给出了 Josh 使用 DP 的行为文章的链接。也许我会为模板中使用的边框编写一个行为,使用 Josh Smith 的仅 DP 方法。谢谢两位!你们摇滚!!

以上是关于按需填充上下文菜单的主要内容,如果未能解决你的问题,请参考以下文章

jQuery上下文菜单插件&;聚乙烯填充物

PySide QPushButton 右键单击​​上下文菜单未分配每个按钮

将上下文菜单添加到特定的 Qtablewdiget 表列,Python

单击时在JavaFX中填充组合框

在使用 Laravel 8 创建模板时使用外键填充字段

Apache Zeppelin + Spark 的按需用户集群?