Контекст
Я работаю с приложением Winforms (.NET 3.5 SP1), которое имеет концепцию рабочих пространств, которая может содержать n номеров панелей.Каждая панель (происходит от Panel
) имеет вид:
.-----------------------.
|Workspace |
|.--------. .--------. |
||Panel1 | |Panel2 | |
||.-----. | |.-----. | |
|||View1| | ||View2| | |
||'-----' | |'-----' | |
|'--------' '--------' |
'-----------------------'
Все панели добавляются в коллекцию this.Controls
класса Workspace (которая происходит от UltraTabPageControl
, элемента управления Infragistics GUI).Каждое представление добавляется в коллекцию Controls
их родителя.Таким образом, когда в рабочую область вызывается Dispose
, панели и виды автоматически располагаются, что вполне ожидаемо и желательно.
У нас есть другая концепция, называемая ViewManager
.Он отслеживает все элементы управления View
в рабочей области и отвечает за поддержание единого «главного» представления.Всякий раз, когда создается View
, он регистрируется у этого менеджера.Это добавляет View
в список, а затем запускает некоторую логику для определения нового «основного» представления, а затем вызывает метод Synchronize()
для каждого представления.
Текущий дизайн таков, что всякий раз, когда View.Dispose()
называется, он отменяет регистрацию от ViewManager
.Это удаляет View
из списка, а затем запускает соответствующую логику, которая проверяет новый мастер, из оставшихся представлений.
Поворот
Когда мызакрывают все рабочее пространство, есть один специальный тип Panel
, который должен быть закрыт перед другими панелями.Итак, в нашем методе Dispose
есть код, который выглядит следующим образом:
protected override void Dispose(bool disposing)
{
var theSpecialPanel = GetSpecialPanel();
if (theSpecialPanel != null)
{
theSpecialPanel.Dispose();
}
base.Dispose(disposing);
}
Если мы уберем этот код, то другие панели могут быть расположены до theSpecialPanel
.Это приводит к тому, что логика, которая проверяет наличие новой главной панели, вызывает Synchronize()
на каждой View
, включая эту специальную панель.Это выдает
"InvalidComObjectException: COM-объект, который был отделен от лежащего в его основе RCW, не может быть использован."
Вопрос
Является ли этот дизайнтакое запах кода?Странно ли добиваться того, чтобы определенный объект располагался раньше других?