Из того, что я понимаю, вы в основном хотите провести рефакторинг большого метода переключения.Поиск в Google для «рефакторинга переключателя» должен дать вам несколько примеров, которые вы можете проверить, чтобы найти то, что вам больше подходит.из каждого блока case
в новый класс, возможно, реализацию интерфейса, общего для всех случаев.Правильная реализация вашего класса будет зависеть от состояния отдельного утверждения case
: это называется шаблон стратегии , потому что каждое условие требует отдельной стратегии.
В вашем случае,вам нужно немного расширить шаблон: у вас есть количество кандидатов для контекстного меню, каждый из которых может обрабатывать определенный тип узла.В этом случае ваш обработчик щелчка правой кнопкой должен позволить им решить, могут ли они обеспечить функциональность для определенного узла.
[Редактировать]
Чтобы пояснить немного, я приведу простой пример.
Я упоминал, что отдельные реализации должны быть извлечены в классы, которые реализуют один и тот же интерфейс, который должен отвечать за изменение внешнего вида и состояния пунктов меню на основетекущее состояние.
interface IMenuStateManager
{
// this method updates state of one or
// more menu elements, according to the
// specified selected node info
void UpdateState(ISelectedNodeInfo info);
}
Наша первая базовая реализация интерфейса IMenuStateManager
не сделает ничего, кроме простого вызова реализаций других менеджеров.Это называется Шаблон составного объекта , поскольку он позволяет нам обрабатывать группу объектов как один объект:
// composite class for a list of menu managers
class CompositeMenuStateManager : IMenuStateManager
{
private readonly IMenuStateManager[] _childManagers;
// params keyword will allow as to pass a comma separated list
// of managers, which is neat
public CompositeMenuStateManager(params IMenuStateManager[] managers)
{
_childManagers = managers;
}
// this is where the job gets done, but composite
// class doesn't do much work by itself
public void UpdateState(ISelectedNodeInfo info)
{
// allow each state manager to change its state
foreach (IMenuStateManager mgr in _childManagers)
{
mgr.UpdateState(info);
}
}
}
Теперь у вас все еще есть огромный список возможных кандидатов меню, но теперь их логика разделена на разные классы, а затем обернута в один составной объект.
IMenuStateManager _menuManager = new CompositeMenuStateManager
(
// note: each menu "manager" can manage one or more
// items, if you find it useful.
// For example, ClipboardMenuStateManager can be
// a composite manager itself (cut/copy/paste).
new ClipboardMenuStateManager(some params),
new SomeOtherMenuItemManager(various params),
new YetAnotherMenuItemManager(various params),
...
);
Я предполагаю, что состояния меню обновляются при выборе узла, но этоэто то, что вы должны легко адаптировать к своему приложению.Этот конкретный обработчик событий передает всю ответственность нашему составному менеджеру меню:
void Node_Selected(sender object, EventArgs args)
{
// find out which node was clicked
Node node = object as Node;
// get the data (model) node for this tree node
INodeData data = node.Tag as INodeData;
// create some info which will be passed to the manager.
// you can pass information that might be useful,
// or just simply pass the node data itself
ISelectedNodeInfo info = new SelectedNodeInfo(data, some other stuff);
// let the manager do the rest of the job
_menuManager.UpdateState(info);
}
Поскольку у вас, вероятно, будет три элемента меню, выполняющих одну и ту же работу одновременно (главное меню, контекстное меню, панель инструментов), выВозможно, вы захотите, чтобы каждая реализация IMenuStateManager
обновляла все три из них одновременно.Самый простой способ - передать массив из ToolStripItem
объектов, который является базовым абстрактным классом для нескольких различных элементов меню:
class PrintMenuManager : IMenuStateManager
{
private readonly ToolStripItem[] _items;
// this constructor can accept several menu elements
public PrintMenuManager(params ToolStripItem[] items)
{
_items = items;
}
public void UpdateState(ISelectedNodeInfo node)
{
foreach (ToolStripItem item in _items)
{
// if node is printable, enable
// all "print" menu items and buttons
item.Enabled = (node.IsPrintable);
}
}
}
При создании экземпляра PrintMenuManager
вы можете передать все кнопкии пункты меню, которые связаны:
// (this should be one of the child managers in
// the composite menu manager, but you get it)
IMenuStateManager printMnuManaegr = new PrintMenuManager
(
this.printMenuItem,
this.printContextMenuItem,
this.printToolbarButton,
);
Вот так, это оказалось длинным в конце.:)
Хорошо, вот и все для начала.