views:

25

answers:

2

I have a large number of ViewModel classes. For each of these classes, there is a corresponding .xaml file which is a 'UserControl'. In my App.xaml, I have them registered as DataTemplates, like so:

<DataTemplate DataType="{x:Type viewModel:MainMenuViewModel}">
     <view:MainMenuView/>
</DataTemplate>

With the idea being that WPF will be able automatically swap in the necessary user controls at runtime. For example, this works:

 <Grid>
    <StackPanel>
    <TextBlock Text="SuperApp" />
        <ItemsControl>
            <ViewModels:MainMenuViewModel/>
        </ItemsControl>
   </StackPanel>
</Grid>

In that the entry "MainMenuViewModel" is automatically replaced by the MainMenuView, bound to the MainMenuViewModel. Great. My current goal is now this: I want to have a button, on, say, a view embedded in the MainMenuView, which opens a popup window, which will have a new ViewModel inside. The idea is to set it up so that I have a single 'generic' popup form, in which I embed an arbitrary ViewModel, and let WPF handle actually rendering it with DataTemplates, similar to the above. So I have a command bound to a button, like so:

<Button Command="{Binding Path=LaunchInStandaloneForm}" Content="Rip Out"/>

Which successfully creates a new window, sets the dataContext equal to the appropriate ViewModel, and shows the window.

The question is: How do I set up the XAML of this popup window so that it will render the appropriate DataTemplate for the ViewModel which is the DataContext? I've tried:

 <Grid>
    <ItemsControl ItemsSource="{Binding Path=.}">

    </ItemsControl>
</Grid>

, but it comes up blank. Any pointers?

+1  A: 

To set the ItemsSource to the DataContext, use ItemsSource={Binding}. That assumes that the DataContext is an enumerable collection of your View Model objects.

Updating with correct answer:

Use a ContentControl :)

Hope that helps.

Kieren Johnstone
In this case, the DataContext is a view model, not a collection of view models. I can obviously change it to be one without much difficulty, but it seems more elegant to have a single one there, rather than a collection of one.
GWLlosa
In that case, what is the name of the property that has the collection you're trying to bind to, relative to the DataContext? Use that as the path, e.g. `ItemsSource={Binding Path=CollectionPropertyOnViewModel}`?
Kieren Johnstone
I don't actually have a collection. I have a single ViewModel in the DataContext, and I want to render a single DataTemplate for that ViewModel, as the only element on the window.
GWLlosa
I believe I missed your whole point. You just want it to use the `DataTemplate` you specified :) Perhaps it's possible to create an `ItemsPresenter` - I know it's usually within a Template though - does that work? I will investigate more now..
Kieren Johnstone
Aha! Try `ContentControl` : http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx
Kieren Johnstone
<Grid> <ContentPresenter Content="{Binding}" /> </Grid>Worked perfectly! Thanks!
GWLlosa
A: 

The accepted answer here shows how to change templates at runtime. You should be able to dig out the answer from that. Any questions just shout.

http://stackoverflow.com/questions/3335834/how-to-modify-silverlight-combobox-data-display/3343652#3343652

Hope that helps

Ben