0

I'm fairly new to WPF and am almost positive I've just overlooked something. I'm having issues preserving the state of user controls within my tabs when I select. It seems very similar to this question but it didn't seem to get resolved.

In my main ViewModel I have an ObservableCollection of the abstract TabableViewModel class. It also implements the INotifyPropertyChanged for the TabControl's SelectedIndex.

I want the TabControl's content to be automatically created so I used a DataTemplate like so:

<Window.Resources>

    <DataTemplate DataType="{x:Type vm:EasyViewModel}">
        <UserControls:EasyControl/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:ComplicatedViewModel}">
        <UserControls:ComplicatedControl/>
    </DataTemplate>
    <DataTemplate x:Key="TabHeaderTemplate">
        <Grid>
            <TextBlock Text="{Binding HeaderText}" />
        </Grid>
    </DataTemplate>
    <Style x:Key="TabItemStyle" TargetType="TabItem">
        <Setter Property="Header" Value="{Binding}" />
        <Setter Property="HeaderTemplate" Value="{StaticResource TabHeaderTemplate}" />
        <Setter Property="Content" Value="{Binding}" />
    </Style>
</Window.Resources>
<TabControl x:Name="contentTab" TabStripPlacement="Bottom" 
      SelectedIndex="{Binding SelectedTabIndex, Mode=TwoWay}"
      ItemsSource="{Binding TabItems, Mode=TwoWay}" 
      ItemContainerStyle="{StaticResource TabItemStyle}">
</TabControl>

EasyControl and ComplicatedControl both have a number of text boxes, combo boxes and other fields. Both ViewModels extend the TabableViewModel class and implement INotifyPropertyChanged.

In a typical test the ObservableCollection will contain one instance of EasyViewModel and then two instances of ComplicatedViewModel. The tabs build themselves properly, but the state of the ViewModels is not being maintained.

If I make changes inside EasyControl, switch to the first ComplicatedControl tab and then switch back, all data has been lost.

If I make changes to the first ComplicatedControl and switch to the second, I get those same changes instead of a blank slate. If I then switch to EasyControl and back again, all data is once again cleared.

I've seen quite a few examples where the DataTemplates are basic, but I haven't seen any where UserControls are picked based on ViewModel type. Is there anything special I have to do to maintain state?

I don't want to break the MVVM pattern by creating the UIElements within the ViewModels. I'm also hoping that I don't have to extend any Tab controls to get this working, but I will if I have to. I'm surprised it's this hard to do.

Community
  • 1
  • 1
Jesster
  • 15
  • 6
  • Your data is in the view model, so if it is being *reset* at any point, then it is *your* code that is resetting it. – Sheridan Mar 11 '14 at 21:28
  • My main form is bound to one view model and contains a collection of other view models that are bound to the tab control. The UserControls in the DataTemplate use these view models for the data and it seems to work when I only interact with a single tab. My problem comes from switching between tabs. – Jesster Mar 12 '14 at 00:11
  • So at the point when you switch tabs, you must initialise one of your view models and that's why it loses its data. You're the only one that can fix this problem... it is *not* reproducible from your code example. – Sheridan Mar 12 '14 at 08:57
  • I... I can't believe how stupid I am. I realized that in the code-behind of my UserControl I still had the view model being initialized from when I was testing. Thank you so much for kicking me out of my mindset and putting me on the right path. – Jesster Mar 12 '14 at 13:23
  • No problem... I'll put my comments into an answer so that this question can be [marked as accepted](http://stackoverflow.com/help/someone-answers), as is customary on this website. – Sheridan Mar 12 '14 at 13:28

1 Answers1

0

So you have a situation where your UI seems to be losing data. This is generally not possible when using MVVM because your data is in your view model and not the view. Therefore, if it is being reset at any point, then it is your code that is resetting it. You said:

My problem comes from switching between tabs

So at the point when you switch tabs, you must initialise one of your view models and that's why it loses its data. You're the only one that can fix this problem... it is not reproducible from your code example. Search for calls to your view model constructor and you should find your problem.

Sheridan
  • 68,826
  • 24
  • 143
  • 183