Reputation: 11
I have very strange problem. I have written application using wpf, telerik(office2007 theme). I use DataTemplateSelector to dynamicly create view for different types of models. In windows 7 all fine and good works, but in windows 8 DataTemplateSelector not work! WTF? Can You help me with my problem?
public class TabDataTemplateSelector:DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if(item==null || container == null)
return null;
FrameworkElement element = Application.Current.MainWindow as FrameworkElement;
if (element == null)
return null;
if (item is PetrochemicalCatalogViewModel)
{
return element.FindResource("PetrochemicalCatalogDataTemplate") as DataTemplate;
}
if (item is FuelPriceViewModel)
{
return element.FindResource("FuelPriceDataTemplate") as DataTemplate;
}
if (item is RoleViewModel)
{
return element.FindResource("RoleDataTemplate") as DataTemplate;
}
if (item is IEquipmentViewModel)
{
return element.FindResource("EquipmentDataTemplate") as DataTemplate;
}
if (item is IZondsViewModel)
{
return element.FindResource("ZondDataTemplate") as DataTemplate;
}
if (item is ITankCatalogViewModel)
{
return element.FindResource("TanksDataTemplate") as DataTemplate;
}
if (item is IDispensersWorkplaceViewModel)
{
return element.FindResource("DispensingDataTemplate") as DataTemplate;
}
if (item is IDispenserSetsWorkplaceViewModel)
{
return element.FindResource("DispenserSetsWorkplaceTemplate") as DataTemplate;
}
if (item is IPaymentTypeCatalogViewModel)
{
return element.FindResource("PaymentTypeWorkplaceTemplate") as DataTemplate;
}
if (item is ICashManagementViewModel)
{
return element.FindResource("CashManagementTemplate") as DataTemplate;
}
if (item is ITerminalWorkplaceViewModel)
{
return element.FindResource("TerminalDataTemplate") as DataTemplate;
}
if (item is IPriceingWorkplaceViewModel)
{
return element.FindResource("PriceingDataTemplate") as DataTemplate;
}
return null;
}
}
<local:TabDataTemplateSelector x:Key="tabDataTemplateSelector"/>
<DataTemplate x:Key="TabContentTemplate">
<telerik:RadBusyIndicator x:Name="rbiBusy" VerticalAlignment="Stretch" IsBusy="{Binding IsBusy}" HorizontalContentAlignment="Stretch" telerik:StyleManager.Theme="Windows8Touch" VerticalContentAlignment="Stretch">
<ContentPresenter ContentTemplateSelector="{StaticResource tabDataTemplateSelector}" Content="{Binding TabContentViewModel}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</telerik:RadBusyIndicator>
</DataTemplate>
Upvotes: 0
Views: 575
Reputation: 89
Things are a little different from windows 7 and windows 8. I had the same issue and what i discovered is that the DataType property is not support for DataTemplate in windows 8, so i had to select it based on their name and use a custom DataTemplateSelector. Here's and extract of my code where a list is filled with different types:
XAML:
<UserControl.Resources>
<s:CustomDataTemplateSelector
x:Key="CustomDataTemplateSelector" />
<DataTemplate
x:Key="Activity1">
<c:ActivityControl1 />
</DataTemplate>
<DataTemplate
x:Key="Activity2">
<c:ActivityControl2 />
</DataTemplate>
</UserControl.Resources>
<Grid>
<ListView
FontSize="20"
BorderThickness="0"
Foreground="Black"
ItemsSource="{Binding Activities}"
HorizontalContentAlignment="Stretch"
ItemTemplateSelector="{StaticResource CustomDataTemplateSelector}" />
</Grid>
CS:
public class CustomDataTemplateSelector : DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
string key = item.GetType().Name;
FrameworkElement element = container as FrameworkElement;
while (element != null)
{
if (element.Resources.ContainsKey(key))
return element.Resources[key] as DataTemplate;
element = VisualTreeHelper.GetParent(element) as FrameworkElement;
}
return Application.Current.Resources[key] as DataTemplate;
}
}
Hope this helps.
Upvotes: 3
Reputation: 69959
The standard way to do what you want would be to put each of your DataTemplate
s into a UserControl
(without the DataTemplate
object, eg. just add the contents), name them ...View
(where '...' comes from the related view model class) and connect them to your view models using DataTemplate
s defined in App.xaml
:
<DataTemplate DataType="{x:Type ViewModels:PetrochemicalCatalogViewModel}">
<Views:PetrochemicalCatalogView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:FuelPriceViewModel}">
<Views:FuelPriceView />
</DataTemplate>
...
<DataTemplate DataType="{x:Type ViewModels:IPriceingWorkplaceViewModel}">
<Views:IPriceingWorkplaceView />
</DataTemplate>
Upvotes: 1