Я пишу MDI-приложение в WPF - документы отображаются на вкладках.
Поскольку на вкладке отображается весь документ, DataTemplate для TabControl, очевидно, довольно сложный, включая некоторый код инициализации / деинициализации в CodeBehind (без хаков - это просто требуется для используемых мной элементов управления, а именно AvalonEdit). Однако проблема заключается в том, что TabControl повторно использует созданный DataTemplate, и когда я меняю активный документ, заменяется только DataContext, исключая все процедуры инициализации / деинициализации, которые выполняются в событиях Loaded / Unloaded.
Я думал о перехвате DataContextChanged
события, но есть одна загвоздка:
Когда DataContext для элемента изменяется, это может повлиять на все связанные с данными свойства этого элемента. Это относится к любым элементам, которые являются дочерними элементами текущего элемента в логическом дереве, которые наследуют контекст данных, а также самого текущего элемента. Все такие существующие привязки должны повторно интерпретировать новый DataContext и пересмотреть результаты привязки. Механизм привязки данных не является детерминированным в отношении порядка этих переоценок относительно возникновения события DataContextChanged. Переоценки могут проводиться до события, после события или в любой смеси.
(источник: https://docs.microsoft.com/pl-pl/dotnet/api/system.windows.frameworkelement.datacontextchanged?view=netframework-4.8)
Таким образом, может случиться так, что все привязки данных будут обновлены (включая AvalonEdit, получающий новый документ) без вызовов деинициализации / инициализации, что приведет к исключению.
Идеальным решением было бы принудительное создание экземпляра представления TabControl каждый раз из DataTemplate, но кажется, что механизм повторного использования представления является общим правилом в WPF (ContentControl также использует его). Менее идеальным, но все же надежным вариантом будет захват изменений DataContext, но мне нужно было бы надежно вызывать код до и после изменения DataContext, и, похоже, это также невозможно.
Как я могу решить эту проблему? Как правильно сохранить (инициализировать / деинициализировать) документ со сложным представлением в WPF?