Задать вопрос
SpacePurr
@SpacePurr
c#, wpf

Как создать независимые вкладки в TabControl?

Здравствуйте.

Требуется создать функционал вкладок 3D моделей как в Autocad или любой другой CAD программе.

Я использую TabControl в WPF, но возникла проблема, которую пока что я не могу обойти по причине незнания или непонимания.

Перейдем к коду.

Имеется некий UserControl Model3DView. В нем содержится DrawingControl3D(я использую библиотеку XBim), который является компонентом отрисовки модели.

<Grid>
    <DrawingControl3D Model={Binding Model}>
        //всякое разное
    </DrawingControl3D>
</Grid>


В основном окне имеется TabControl,
где Models - коллекция объектов Model3DTab, которые, в свою очередь, содержат свойства, состояния и прочее для каждой конкретной модели(Model, SelectedEntity и прочее, что нужно будет привязать в DrawingControl3D):
<TabControl ItemsSource="{Binding Models}" SelectedItem="{Binding CurrentTab, Mode=TwoWay}">   
    <TabControl.ItemTemplate>
        <DataTemplate>
           //Заголовок
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate DataType="{x:Type vm:Model3DTab}">
            <views:Model3DView/>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>


Теперь пример, плавно перерастающий в суть вопроса.

Для того, чтобы скрыть элементы, например, мне нужно обратится к экземпляру DrawingControl3D и передать в коллекцию скрываемых элементов определенный элемент и вызвать у контрола метод ReloadModel.
var hiddens = new List<IPersistEntity>{ entity };
drawingControl3D.HiddenInstances = hiddens;
drawingControl3D.ReloadModel();


Когда вкладок у меня не было, я получал экземпляр текущего DrawingControl3D из события Loaded через Interactions.Triggers и в своей ViewModel сохранял в переменную.
<i:EventTrigger EventName="Loaded">
    <ei:CallMethodAction MethodName="DrawingControl3D_OnLoaded" TargetObject="{Binding}"/>
</i:EventTrigger>


И так бы и делал с несколькими вкладками, написав обработчик событий в классе Model3DTab, но проблема в том, что не смотря на создание вкладок(через добавление элементов к привязанной коллекции Models), событие срабатывает только один раз при создании самой первой вкладки.

Да, Binding работает и я имею разные модели в каждой вкладке, только вот при переключении они каждый раз подгружаются(видимо смена свойств), а что касается непривязанных свойств, например та же коллекция HiddenInstances, то она сохраняется для других вкладок, потому как экземпляр DrawingControl3D всегда один и тот же.

На сколько я понимаю это нормальная работа TabControl, то есть создание одного экземпляра из ContentTemplate, но мне нужно, чтобы экземпляры были разными и независимыми друг от друга. Конечно, я не знаю еще на сколько сильно это скажется на потреблении памяти и прочее с моделями больших размеров, но все же.

1. Можно ли через TabControl создавать каждый раз новые экземпляры вкладок?(на стаке один раз мелькнуло свойство Shared, но не дало результатов, не исключаю что руки у меня кривые)
2. Работает ли ItemsControl также как TabControl в плане создания экземпляра?

ps: для решения проблемы непривязанных свойств я могу переписать контрол, создав DependencyProperty для каждой коллекций скрываемых/изолируемых элементов, стилей и прочего(чтобы сделать {Binding HiddenInstances}) и в событии изменения вызывать обновление модели, но я не думаю что этот подход правильный. Поправьте меня, пожалуйста, если моя точка зрения ошибочна.

Спасибо.
  • Вопрос задан
  • 409 просмотров
Подписаться 2 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
Проблема с кешированием TabItem, скорее всего.
Попробуйте воспользоваться
<TabControl b:TabContent.IsCached=“True”>
</TabControl>

Отсюда: https://www.codeproject.com/Articles/460989/WPF-Ta...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы