I am trying to modify a existing WPF application in a way so that a newer version of some data object can be used alongside the old one. And so i avoid redundant code by extending the existing ViewModel with new fields where the old ones cannot be reused.
public IList<G1VU.PDR> VuG1 { get; set; }
public IList<G2VU.PDR> VuG2 { get; set; }
public PlacesCompound VuP
{
get
{
if (VuG1 != null && VuG2 == null)
{
return new PlacesCompound {
G1 = VuG1,
G2 = null
};
}
if (VuG2 != null && VuG1 == null)
{
return new PlacesCompound {
G1 = null,
G2 = VuG2
};
}
throw new Exception("G1 and G2 data present or no data present");
}
}
VuG1
has existed before and i have added a new property VuG2
for the new data. As you can see these are not the same class so i cannot interchange them. For that reason i've added a property that will return either of the two in a PlacesCompound
class, which is just a class with two properties and nothing else.
In the corresponding usercontrol (lets call it ActivitiesView) we have a DataGrid which binds to the ViewModel and somewhere a TabItem that will display a custom UserControl places
which binds to VuG1
on the ViewModel. I have copied it and changed it so it will work with VuG2
Data.
And i created a custom DataTemplateSelector
which will decide what Template to use based on which variable of PlacesCompound
isnt null
.
In VUActivitiesResources.xaml
i have then declared 2 DataTemplates one for each places
UserControl and the DataTemplateSelector.
<activities:VUActivitiesViewDataTemplateSelector x:Key="PlacesTemplateSelector"/>
<DataTemplate x:Key="VuG2Template">
<places:VUPViewG2 DataContext="{Binding VuG2}" HorizontalAlignment="Left"/>
</DataTemplate>
<DataTemplate x:Key="VuG1Template">
<places:VUPViewG1 DataContext="{Binding VuG1}" HorizontalAlignment="Left"/>
</DataTemplate>
VUActivitiesResources.xaml
is being referenced in ActivitiesView as UserControl.Resources
.
In the ActivitiesView i placed a ItemsControl into the TabItem replacing the custom places
UserControl (ive also tried a ListBox instead of a ItemsControl, but neither works)
<TabItem IsEnabled="{Binding PlacesIsVisible}">
...
<ItemsControl
ItemsSource="{Binding VuP}"
ItemTemplateSelector="{StaticResource PlacesTemplateSelector}"></ItemsControl>
</TabItem>
My question: why PlacesTemplateSelector
is never used and how do i make it being used? Because right now while debugging i can see that in ViewModel VuP
returns a PlacesCompound
object correctly but the Selector is never entered. I want one of the two DataTemplates to show up in the TabItem and right now none is showing.
ItemsSource must be a collection (which your PlacesCompound is not), in your case this would be either VuG1 or VuG2. If the two item classes have no common base class, you can still use IEnumerable
:
public IEnumerable VuP => (IEnumerable)VuG1 ?? VuG2;
Then, instead of writing a TemplateSelector, just let the WPF DataTemplating mechanism do its work:
<DataTemplate DataType="{x:Type namespace1:PDR}">
<places:VUPViewG2 HorizontalAlignment="Left"/>
</DataTemplate>
<DataTemplate DataType="{x:Type namespace2:PDR}">
<places:VUPViewG1 HorizontalAlignment="Left"/>
</DataTemplate>
<ItemsControl ItemsSource="{Binding VuP}" />