S
S
Space Purr2020-02-24 21:33:14
WPF
Space Purr, 2020-02-24 21:33:14

How to create independent tabs in TabControl?

Hello.

It is required to create the functionality of 3D models tabs as in Autocad or any other CAD program.

I'm using a TabControl in WPF, but there's a problem that I can't get around yet due to ignorance or misunderstanding.

Let's move on to the code.

There is some UserControl Model3DView . It contains a DrawingControl3D (I'm using the XBim library) which is the rendering component of the model.

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


The main window has a TabControl ,
where Models is a collection of Model3DTab objects , which, in turn, contain properties, states, and so on for each particular model ( Model , SelectedEntity , and so on that will need to be bound in 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>


Now an example that smoothly develops into the essence of the issue.

In order to hide elements, for example, I need to access the DrawingControl3D instance and pass a certain element to the collection of hidden elements and call the ReloadModel method on the control .
var hiddens = new List<IPersistEntity>{ entity };
drawingControl3D.HiddenInstances = hiddens;
drawingControl3D.ReloadModel();


When I didn’t have tabs, I got an instance of the current DrawingControl3D from the Loaded event via Interactions.Triggers and saved it to a variable in my ViewModel .
<i:EventTrigger EventName="Loaded">
    <ei:CallMethodAction MethodName="DrawingControl3D_OnLoaded" TargetObject="{Binding}"/>
</i:EventTrigger>


And I would have done this with several tabs by writing an event handler in the Model3DTab class , but the problem is that despite the creation of tabs (by adding elements to the bound Models collection ), the event fires only once when the very first tab is created.

Yes, Binding works and I have different models in each tab, only when switching they are loaded every time (probably changing properties), and as for unbound properties, for example, the same HiddenInstances collection , it is saved for other tabs, because as an instance of DrawingControl3D always the same.

As far as I understand, this is the normal operation of TabControl, i.e. creating one instance from ContentTemplate , but I need the instances to be different and independent of each other. Of course, I don't know how much it will affect memory consumption and so on with large models, but still.

1. Is it possible to create new instances of tabs every time through TabControl ? (The Shared property flashed once on the stack , but it did not give results, I do not exclude that my hands are crooked)
2. Does ItemsControl work the same as TabControl in terms of creating an instance?

ps: to solve the problem of unbound properties, I can rewrite the control by creating a DependencyPropertyfor each collection of hidden / isolated elements, styles and other things (to make {Binding HiddenInstances} ) and in the change event, call the model update, but I don’t think this approach is correct. Please correct me if my point of view is wrong.

Thank you.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Vinogradov, 2020-03-05
@genI3

TabItem caching issue, most likely.
Try to use

<TabControl b:TabContent.IsCached=“True”>
</TabControl>

From here: https://www.codeproject.com/Articles/460989/WPF-Ta...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question