开发者

Pattern / Methodology For Dynamic ContextMenu Based on Collection of Objects

开发者 https://www.devze.com 2023-01-08 05:21 出处:网络
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

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 typ开发者_运维百科e 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 *


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

0

精彩评论

暂无评论...
验证码 换一张
取 消