DataTemplateSelector и Windows 8

У меня очень странная проблема. Я написал приложение, используя wpf, telerik(тема office2007). Я использую DataTemplateSelector для динамического создания представления для разных типов моделей. В Windows 7 все хорошо и хорошо работает, но в Windows 8 DataTemplateSelector не работает! WTF? Можете ли вы помочь мне с моей проблемой?

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>

2 ответа

Вещи немного отличаются от Windows 7 и Windows 8. У меня была та же проблема, и я обнаружил, что свойство DataType не поддерживает DataTemplate в Windows 8, поэтому мне пришлось выбрать его на основе их имени и использовать пользовательский DataTemplateSelector, Вот и извлечение моего кода, где список заполнен разными типами:

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;
    }
}

Надеюсь это поможет.

Стандартный способ сделать то, что вы хотите, это поставить каждый из ваших DataTemplateс в UserControl (без DataTemplate объект, например просто добавьте содержимое), назовите их ...View (где '...' происходит из соответствующего класса модели представления) и соедините их с вашими моделями представления, используя DataTemplateопределены в 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>
Другие вопросы по тегам