3

Got a view with lots of objects inside, which get their View from a DataTemplate declaration:

<DataTemplate DataType="{x:Type vm:StatusAViewModel}" >
    <vw:StatusAView />
</DataTemplate>

<DataTemplate DataType="{x:Type vm:StatusBViewModel}" >
    <vw:StatusBView />
</DataTemplate>

Now I want to show a popup with its content based on the type of the data it's to contain:

<Popup AllowsTransparency="True"
       IsOpen="{Binding IsPopupOpen,Mode=OneWay}" 
       PlacementTarget="{Binding PopupPlacementElement}" Placement="{Binding PopupPlacementMode}"
       HorizontalOffset="{Binding PopupHOffset}" VerticalOffset="{Binding PopupVOffset}">
    <ContentPresenter x:Name="StuckHere" Content="{Binding PopupData}" />
</Popup>

A ContentTemplateSelector on StuckHere doesn't work because it's only evaluated once and when the PopupData changes, the template isn't re-selected.

All the examples I can find rely on a default datatemplate, which I can't use in my case because I've already got a default DataTemplate for the main view, I only want this different template to affect my popup.

Any clues?

AndyC
  • 353
  • 3
  • 15
  • "A ContentTemplateSelector on StuckHere doesn't work because it's only evaluated once **and when the PopupData changes**, the template isn't re-selected." Isn't that what you want? –  Aug 22 '12 at 19:11
  • 1
    Two ideas here: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/4fd42590-8375-46d0-b7bc-6c217df0f0ba/ .... http://social.msdn.microsoft.com/Forums/en/wpf/thread/a60970c7-c3fd-4a0c-bf83-c10c8103c4e4 .... other answer here: http://stackoverflow.com/questions/2085467/explicitly-refresh-datatemplate-from-a-datatemplateselector – Colin Smith Aug 22 '12 at 19:32
  • @Will - No - PopupData will change depending on user clicks, depending what data was clicked depends which Template I want. – AndyC Aug 24 '12 at 10:17
  • @colinsmith - The first idea feels very close, still can't see how to actually use it as my popup view, though. The popup comes out as "System.Windows.DataTemplate", as though the framework doesn't know how to actually present the view. I now have another View for the popup, so the Popup content is now `` and my view contains the two ControlTemplates plus a DataTemplate containing the Control and DataTemplate.Trigger in the resources and a ``. I see why, but not what to do!??? – AndyC Aug 24 '12 at 10:27
  • Ah that last question is a red herring - see Rachel's solution below. – AndyC Aug 24 '12 at 10:40

2 Answers2

9

You can apply a different set of DataTemplates in <Popup.Resources>, which will override the ones defined higher up in the visual tree and apply to that Popup only

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:StatusAViewModel}" >
        <vw:StatusAView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:StatusBViewModel}" >
        <vw:StatusBView />
    </DataTemplate>
</Window.Resources>

<Popup>
    <Popup.Resources>
        <DataTemplate DataType="{x:Type vm:StatusAViewModel}" >
            <vw:StatusAPopupView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:StatusBViewModel}" >
            <vw:StatusBPopupView />
        </DataTemplate>
    </Popup.Resources>

    <!-- The DataTeplate used here will be a PopupView, not the regular View -->
    <ContentPresenter Content="{Binding PopupData}" />
</Popup>
Rachel
  • 130,264
  • 66
  • 304
  • 490
0

You may take a look at http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx. Implement a templateselector derived from DateTemplateSelector and use a ContentControl. Bind the Content to your DataObject and the ContentTemplateSelectorTemplate to your TemplateSelector.

Florian
  • 5,918
  • 3
  • 47
  • 86
  • Therein lies the problem - the template is only selected once and if the type of PopupData changes, the template doesn't change with it because it is only evaluated once. – AndyC Aug 24 '12 at 10:32