Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
662 views
in Technique[技术] by (71.8m points)

wpf - Why do tab controls reuse View instances when changing tab

I have a WPF project following an MVVM pattern.

I have one control that contains a tab control. The tab control binds to an observable collection. Each item in the observable collection is a view model for a specific tab page to be shown.

The xaml file implementing the tab control uses a data template to select a specific user control to display, depending on the concrete type of the view model in the observable collection.

The strange behavior I observe is, when I change between two tabs of a different type, a new instance of the user control is created. When I change between two tabs of the same type, WPF reuses the same instance of the user control, it just changes the DataContext on the control.

This has some very unfortunate consequences, e.g. when changing between two tabs of the same type, but with different visual state, then the visual state transition animation is displayed, where it should not; the change should be instant. Also some exceptions occur when changing between two tabs of different type.

Can I change this behavior so the tab control will hold one instance of the user control for each tab page, and not "destroy" the controls, when switching to a different tab.

<UserControl.Resources>
    <DataTemplate DataType="{x:Type ViewModels:ConcreteViewModel1}" d:IsDataSource="true">
        <Views:ConcreteView1 />
    </DataTemplate>
    <DataTemplate DataType="{x:Type ViewModels:ConcreteViewModel2}" d:IsDataSource="true">
        <Views:ConcreteView2/>
    </DataTemplate>
    ...
</UserControl.Resources>

<Grid x:Name="ControlTabLayoutRoot">
    <TabControl Grid.Row="0" x:Name="Main_TabControl"
        ItemsSource="{Binding MainTabControl}"
        SelectedIndex="{Binding SelectedIndex}" 
        IsSynchronizedWithCurrentItem="True"
        HorizontalContentAlignment="Stretch" 
        VerticalContentAlignment="Stretch"
        ItemContainerStyle="{DynamicResource CustomTabItemStyle}"
        Style="{DynamicResource CustomTabControl}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock>                 
                <TextBlock.Text>
                  <MultiBinding Converter="{StaticResource tabItemHeaderConverter}">
                      <MultiBinding.Bindings>
                          <Binding/>
                          <Binding Path="ProtocolName"/>
                      </MultiBinding.Bindings>
                  </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </DataTemplate>
    </TabControl.ItemTemplate>
    </TabControl>
</Grid>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A TabControl does recycling virtualization internally. You can find two different approaches to prevent this in this StackOverflow questions:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...