基于对象集合的动态上下文菜单的模式/方法

发布于 2024-09-11 04:15:30 字数 1338 浏览 2 评论 0原文

背景

我有一个 TreeView,它遵循 MVVM 设计模式,并通过在列表中记录 TreeViewItem 选择来支持多重选择。目前,有多种类型的 TreeViewItem 可供用户选择。

它们是:

  • WorldFolderMyDataFodler 类型的两个 Root 节点,它们可以包含子 Folder 类型
  • Child Folder LocationFolder、PersonFolder、CollectionFolder 类型的 节点
  • LocationItem、PersonItem 类型的子 Item 节点
  • CollectionFolder 可以包含 Folder 类型的子节点

总之,只需很少的代码就可以很好地工作,并且支持位置和人员的集合以及集合中的集合。

问题/疑问

我的顶级视图模型跟踪 TreeViewItems 的选择状态,当前选择可能是 ItemFolder 的组合甚至是 Root 类型节点。根据用户的选择,我想创建一个动态上下文菜单。到目前为止这有效!当我选择多个 LocationItem 和/或 PersonItem 类型节点时,我的视图模型会生成一个自定义上下文菜单。问题是复杂性!我的视图模型很快变成了几十个 if/else if/else 语句来捕获所有可能的排列!

例如:

if (_selectedItems.All(item => item is PersonItem)) // Only people selected
{ 
  // Create ContextMenu based on only PersonItems 
}
else if( _selectedItems.All(item => item is LocationItem)) // Only Locations
{
  // Create ContextMenu based only on LocationItems
}
...

是否有更好的方法来处理用户选择的所有可能排列并更有效地生成我的 ContextMenus?

* 对代码格式感到抱歉,整个星期都让我感到悲伤 *

Background

I have a TreeView that follows the MVVM design pattern and supports multiple selection by recording TreeViewItem selections in a List. As it stands there are several types of TreeViewItems available for the user to select.

They are:

  • Two Root nodes of type WorldFolder and MyDataFodler which can contain child Folder types
  • Child Folder nodes of types LocationFolder, PersonFolder, CollectionFolder
  • Child Item nodes of type LocationItem, PersonItem
  • CollectionFolder can contain child nodes of Folder types

In all this works very well with very little code and supports collections of Locations and People and furthermore Collections within Collections.

Problem / Question

My top level view-model keeps track of the selection state of TreeViewItems and the current selection may be a combination of Item, Folder or even Root type nodes. Depending on the user's selection I want to create a dynamic ContextMenu. So far this works! When I select several LocationItem and/or PersonItem type nodes my view-model generates a custom ContextMenu. The problem is the complexity! My view-model is quickly turning into dozens of if/else if/else statements to capture all the possible permutations!

For example:

if (_selectedItems.All(item => item is PersonItem)) // Only people selected
{ 
  // Create ContextMenu based on only PersonItems 
}
else if( _selectedItems.All(item => item is LocationItem)) // Only Locations
{
  // Create ContextMenu based only on LocationItems
}
...

Is there a better way to handle all the possible permutations of user choices and generate my ContextMenus more efficiently?

* Sorry about the code formatting, it's been giving me grief all week *

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柒七 2024-09-18 04:15:30

我不记得在哪里读到过这样一句至理名言:
使用 TreeView 的最佳方式不是不使用 TreeView,

这是什么意思?将功能移至树节点中,并尽可能保持树视图为缩略图。不幸的是,默认情况下树节点没有很多事件,但是很容易将树视图事件重定向到节点。

完成后,您可以覆盖节点中的 ContextMenuStrip 属性。第一个选定的节点创建它想要处理的 ToolStripItems 列表,并询问允许哪些树视图(例如使用 FilterMenuItems(desiredItems) 方法)。树视图询问所有选定的节点它们能够处理哪些节点。结果就是您的上下文菜单。

这应该适用于几乎任何数量的不同节点,并使树(节点)易于维护。

编辑:该死!错过了 WPF 标记,因此我无法评估可用事件,因为我尚未使用 WPF

I can't remember where I read this wise saying:
The best way to work with a TreeView is not not to work with the TreeView

What does this mean? Move the functionality into the tree nodes and keep the tree view as thumb as possible. Unfortunately, by default the tree node does not many events, though, it's easy to redirect the tree view events to the nodes.

Once done, you can override the ContextMenuStrip property in your nodes. The first selected node creates the list of ToolStripItems it wants to handle and asks the tree view which are allowed (e.g. with a FilterMenuItems(desiredItems) method). The tree view asks all selected nodes which of the nodes they would be able to handle. The result is your context menu.

This should work with almost any count of different nodes and keeps the tree (nodes) easy to maintain.

Edit: Dang! Missed the WPF tag, so I cannot asses the available events, since I did not yet work with WPF

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文