简体   繁体   中英

WPF DataTemplateSelector is not used

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}" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM