views:

116

answers:

1

I have a TDI, bound to an observable collection of workspaces (all based on Josh Smith's MVVM Demo). On one tab, there is a user control, also bound to an observable collection. If I switch tabs, the user control always jumps back to the 1st item.

I'm kinda desperate. I searched since 5 hours now but just I can't figure out why it does this or where to search.

I simplified the whole thing as far as I could and uploaded it to: http://mad-scientists.co.uk/share/TestCandiMan.zip (about 1,5MB)

Your help is greatly appreciated!

I use C# Express 2008.

+1  A: 

The problem here is that the TabControl instantiaties a new DataTemplate for its content each time you select another tab item, so your view is recreated with everything sets to default. You must implement a mechanism to have an unique view for a given view model. Without MVVM you would just add a View property to the ViewModel but that's largely defeating the purpose of MVVM here.

Edit following your comments: what I meant is that each time you're switching tab, the TabControl will display its content using a new visual tree from the DataTemplate.

Let's take an example:

  1. You select the tab #1, its content is a CustomerViewModel. A new visual tree (from your NewCustomerView) is created from the DataTemplate and shown on the TabControl. The caret is in the first textbox, the tab has its first index selected, etc.

  2. You select tab #2. Content from tab #1 is not anymore in the visual tree and is discarded. The content from tab #2 will follow the same process as 1. to build a tree.

  3. You select tab #1 again. Content from tab #2 is not anymore in the visual tree and is discarded. And here, the same mechanism activates again. A new visual tree is built from the DataTemplate, with everything at its default. Woops! But that's normal since WPF's ContentPresenter won't keep a content's tree in memory for every possible object that has been its content once.

=> The theorical solution, build yourself your visual. For example, in a totally imperfect world, creates an unique NewCustomerView in your CustomViewModel, and exposes it via a property, ley's say View. The new DataTemplate that you'll use will be :

<DataTemplate DataType="{x:Type CustomerViewModel}">
    <ContentPresenter Content="{Binding View}" />
</DataTemplate>

And voila, when a visual tree is created from the template, the presenter will be a totally new one, but the View is unique and won't be recreated so the caret will be at the same place the user left it, same thing for the tabs.

But, like I said before, this don't go well at all with MVVM philosophy. Try to build a static class that is able to return an unique View for a given ViewModel, or something like that.

Another solution will be to add to your ViewModel things like SelectedTabIndex and bind them, CurrentFocusPosition and such but that's totally view-related to me.

Julien Lebosquain
hmmm ... that means I cannot use the same DataTemplate (e.g. customer basic data) for displaying and creating at the same time in that scenario? thats too bad, cause it means some redundancy
MAD9
I think I misunderstood you, because I just added the function to add an empty tab. Even though this has nothing to do with the existing customers view and data template, the customer tab jumps back to item No. 1 like before ...
MAD9
Updated my answer following your comments.
Julien Lebosquain
Thank you very much! Even though I was hoping there would be an easier solution ... =/
MAD9