10

I have a fairly basic WPF UI whereby user requests cause a new tab to open in my TabControl. The TabControl is bound to an ObservableCollection<ViewModelBase>

I add ViewModel instances to this collection, and the corresponding tab's content is displayed based on templates like this:

    <DataTemplate DataType="{x:Type viewModels:UserUploadsViewModel}">
        <userControls:UserUploads />
    </DataTemplate>

Now let's say that inside of the UserUploads control I'd like to wire up a ViewModel in XAML to help with the designing, like this:

<UserControl x:Class=".....UserUploads"
   .....
    DataContext="{Binding Source={StaticResource ViewModelLocater},
                  Path=UserAdministrationViewModel}">

This property will return a ViewModel with live services at runtime, and a ViewModel with mock data at design time.

Question: Will this XAML interfere with what I'm doing in binding a TabItems content to a ViewModel instance, and relying on the dataTemplate above to render the right View? If so, is there a way to get both of these concepts to work together?

Revious
  • 7,816
  • 31
  • 98
  • 147
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393

3 Answers3

31

There is an easier way to do this. Have a DesignTimeUserAdministrationViewModel and populate it with static data in the constructor and refer that in UserControl as:

<UserControl d:DataContext="{d:DesignInstance designTimeVMs:DesignTimeUserAdministrationViewModel, IsDesignTimeCreatable=True}">

This way you have a design time test data bound to d:DataContext and runtime live data bound to the actual DataContext. More details here.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
anivas
  • 6,437
  • 6
  • 37
  • 45
  • That looks great. So if it's design time, that (design time view model) object will be wired up, but at runtime it'll do nothing? – Adam Rackis Jul 14 '11 at 18:08
  • 1
    Yes, it's added for blendability. – anivas Jul 14 '11 at 18:17
  • Fantastic! Using `IsDesignTimeCreatable=True` will populate the view with data. If set to `False`, it will only provide the "shape" of the data, which gives full data binding support in the designer, instead of binding blindly. Also, you can use a .xaml file to fully specify example data with `{d:DesignData}`. See [Walkthrough: Using a DesignInstance to Bind to Data in the Designer](http://msdn.microsoft.com/en-us/library/dd490796(VS.100).aspx) and [Walkthrough: Using Sample Data in the WPF Designer](http://msdn.microsoft.com/en-us/library/ee823176(v=vs.100).aspx) – cod3monk3y Jul 21 '14 at 20:58
  • This solution is super! – peter70 Oct 06 '14 at 12:36
  • 5
    Your link is dead - you deleted your WordPress site – CAD bloke Apr 16 '16 at 23:09
  • The link to the answer has gone stale, but the MSDN page for a walkthrough of setting up design instance data context for editing XAML markup is explained here: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/dd490796(v=vs.100) – Tore Aurstad Jun 27 '19 at 18:22
1

The built in MS stuff is not bad, but another more elegant and structurally sound alternative which I am busy incorporating in my project is: http://msdn.microsoft.com/en-us/magazine/dn169081.aspx

Basically, you use the MVVM Light toolkit with the SimpleIoc container it comes with and end up with the ability to serve up data for the following three scenarios:

Design time, Run time, and Test time.

Better still, the whole point of MVVM Light is to have your stuff be directly editable in Blend and there is a whole series of videos and blogs and sample apps describing it all. I wish I had found these earlier in my WPF explorations.

Dirk Bester
  • 1,791
  • 19
  • 21
1

Yes I think it will interfere with your current setup

The ViewModelLocator is a static class that returns a dummy object at design time, and a static ViewModel at runtime. This means that

  • The ViewModelLocator, not your ParentViewModel, contains your TabViewModels

  • You cannot have multiple instances of the same Tab (ViewModel) open at once

  • You cannot manage Open/Closed tabs unless you reference the UserControl, which is a violation of the MVVM principle where the ViewModel doesn't know of the View

  • You can't instantiate new copies of the TabViewModel with parameterized constructors. For example, OpenTabs.Add(new CustomerViewModel(CustomerId));

Perhaps an alternative could be a Converter? One that returns a static object if in design time, or the bound object during runtime? I've never tested such a thing but in theory it should work :)

Rachel
  • 130,264
  • 66
  • 304
  • 490