WinRT: как получить доступ к ItemsSource родителя в DataTemplateSelector ContentControl

мне нужна помощь для моего WindowsStoreApp с использованием XAML/C#.

Давайте начнем с очень краткого объяснения моей проблемы, а если оно недостаточно понятно, то ниже вы найдете очень подробную информацию :)

Вкратце: у меня есть ContentControl внутри GridView. GridView имеет ItemsSource набор для коллекции. В моем ContentControl я хочу использовать самодельный DataTemplateSelector. В этом SelectTemplateCore-методе мне нужен доступ к элементам GridView ItemsSource - как я могу сделать это в WinRT?

В деталях:

Я хочу отображать папки системы пользователя, такие как библиотека изображений, подключенные USB-устройства и т. д. Разные типы папок должны иметь разные значки. Некоторые значки у меня есть как данные пути XAML, а некоторые - как файлы изображений. Папки хранятся в коллекции. Эта коллекция (названная «Ordner») хранится в модели просмотра страницы. Каждая папка имеет свойство (на основе перечисления), которое определяет ее тип. Сначала я использую пользовательский DataTemplateSelector, чтобы проверить, может ли тип папки отображаться через изображение или через путь. Это работает отлично.

Код для этого здесь... У меня есть такая страница:

<common:LayoutAwarePage [...]
    xmlns:common="using:De.Mms.DiplomSnma.Win8App.Common">
    <common:LayoutAwarePage.Resources>
        <common:OrdnerDataTemplateSelector x:Key="ordnerTemplateSelector"
            TemplatePathquelle="{StaticResource PathquelleDataTemplate}"
            TemplateBildquelle="{StaticResource BildquelleDataTemplate}" />
    </common:LayoutAwarePage.Resources>

    <GridView ItemsSource="{Binding Ordner}" ItemTemplateSelector="{StaticResource ordnerTemplateSelector}" >
        [...]
    </GridView>
</common:LayoutAwarePage>


class OrdnerDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate TemplateBildquelle { get; set; }
    public DataTemplate TemplatePathquelle { get; set; }

    protected override DataTemplate SelectTemplateCore
        (object item, DependencyObject container)
    {
        OrdnerViewModel ordner = item as OrdnerViewModel;
        if (ordner.OrdnerTyp.Equals(EnumClass.OrdnerTyp.Sharepoint))
        {
            return TemplateBildquelle;
        }
        else
        {
            return TemplatePathquelle;
        }
    }
}

Если значок папки основан на пути, вызывается DataTemplate с именем "PathquelleDataTemplate" в ResourceDictionary. Внутри DataTemplate есть, помимо других UI-элементов, мой ContentControl. Здесь я хотел использовать другой сделанный на заказ DataTemplateSelector, чтобы снова проверить тип папки и выбрать соответствующий DataTemplate, который затем содержит правильный путь и его данные. Но, конечно, я не мог просто использовать item в перезаписанном SelectTemplateCore(item, container). Без DataContext item будет null. Как я могу сослаться на ItemsSource моего (родителя-родителя-)родителя GridView? Я совершенно не могу указать DataContext. Каждая часть справки, которую я нашел, основана на WPF и, похоже, не работает в WinRT. Или есть совершенно другой, но более подходящий способ получить доступ к Коллекции?

Вот DataTemplate «PathquelleDataTemplate» (в ResourceDictionary).

<DataTemplate x:Key="PathquelleDataTemplate">
    <Grid Height="160" Width="220">
        <StackPanel Orientation="Vertical" Background="White">
            [...]
            <StackPanel Orientation="Horizontal">
                <ContentControl ContentTemplateSelector="{StaticResource iconTemplateSelector}" />
                [...]
            </StackPanel>
        </StackPanel>
    </Grid>
</DataTemplate>

И здесь, просто в качестве примера, один из DataTemplates будет выбран DataTemplateSelector:

<DataTemplate x:Key="BildOrdnerIconCCTemplate">
    <Path Fill="Black" Data="[...ThePathData...]"/>
</DataTemplate>

Заранее спасибо за любую помощь и извините, если мой английский иногда звучит немного странно :)


person SunnyBunny    schedule 08.03.2014    source источник
comment
Ваш английский был великолепен! И структура вашего вопроса тоже была фантастической. Во-первых, я бы передал DataContext из PathquelleDataTemplate в ContentControl вот так: <ContentControl ContentTemplateSelector="{StaticResource iconTemplateSelector}" Content="{Binding}"/>. Таким образом, iconTemplateSelector должен получить Item для обработки.   -  person Nate Diamond    schedule 08.03.2014
comment
О, правда, это было так просто? позор мне ;) При первой попытке казалось, что это не сработает, но потом я заметил, что метод SelectTemplateCore вызывается дважды для каждого элемента, сначала с item=null, а затем с правильно установленным элементом.. . Большой! Большое спасибо!   -  person SunnyBunny    schedule 09.03.2014


Ответы (1)


Установите Content на DataContext, передаваемое в PathquelleDataTemplate, т.е.

<ContentControl ContentTemplateSelector="{StaticResource iconTemplateSelector}" Content="{Binding}"/>

Как вы заметили, iconTemplateSelector получит два элемента: null, а затем свойство. Значение null используется, когда сначала применяется шаблон, а второе — когда разрешается привязка.

person Nate Diamond    schedule 09.03.2014