Можете ли вы использовать CollectionViewSource внутри DataTemplate? - PullRequest
5 голосов
/ 20 октября 2010

Можно ли явно использовать CollectionViewSource внутри шаблона данных? Обычно мы помещаем CollectionViewSource в ресурсы вместе с шаблоном, но наша модель этого не допускает, потому что «source» collectionviewsource является свойством DataContext на этом уровне дерева, то есть должен существовать экземпляр на этом уровне. Если поместить его в корень ресурсов, это будет означать только один экземпляр. Мы также не можем просто использовать группировку на внешнем уровне, поскольку эти элементы не существуют, пока вы не окажетесь так далеко вниз по иерархии, и не у всех братьев и сестер даже есть это свойство. Поэтому логично, что мы создаем экземпляр CollectionViewSource в DataTemplate (в данном случае это HierarchicalDataTemplate, но это не имеет значения.)

В частности, мы пытаемся разрешить определенную сортировку на этом конкретном уровне узла. Наш единственный другой выбор - сортировка в самой ViewModel, но это становится проблемой, поскольку мы используем ObservableCollections, которые сами не поддерживают сортировку. Фактически, в каждой статье, которую мы видели по этой теме, говорится, что именно по этой причине вы должны использовать CollectionViewSource, отсюда и этот вопрос.

Например, это работает…

<HierarchicalDataTemplate x:Key="CategoryTemplate"
    ItemTemplate="{StaticResource TreeViewSymbolTemplate}"
    ItemsSource="{Binding Symbols}">

    <TextBlock Text="{Binding Name}" FontWeight="Bold" />

</HierarchicalDataTemplate>

Но это не…

<HierarchicalDataTemplate x:Key="CategoryTemplate"
    ItemTemplate="{StaticResource TreeViewSymbolTemplate}">

    <HierarchicalDataTemplate.ItemsSource>
        <Binding>
            <Binding.Source>
                <CollectionViewSource Source="{Binding Symbols}" />
            </Binding.Source>
        </Binding>
    </HierarchicalDataTemplate.ItemsSource>

    <TextBlock Text="{Binding Name}" FontWeight="Bold" />

</HierarchicalDataTemplate>

Мне кажется, что это так, но это не так. Опять же, мы не можем разместить CollectionViewSource на том же уровне, что и шаблон данных, поскольку для каждого шаблона должен быть один экземпляр, так как каждый имеет свой собственный набор элементов (хотя все они будут иметь общие критерии сортировки.)

M

1 Ответ

3 голосов
/ 21 октября 2010

Хорошо ... так что это не совсем то, что я хотел сделать, но результат точно такой же, и никто даже не прокомментировал, не говоря уже о ответе, поэтому я назвал это единым целым.

Первоначальная причина, по которой нам нужно было это сделать, - сортировка по узлам.Хотя мы никогда не заставляли работать CollectionViewSource, нам удалось применить сортировку непосредственно к узлам.Хитрость заключается в том, чтобы сделать это либо во время создания узла, либо так, как мы это делаем, когда узел расширяется (мы используем связывание, поэтому мы не создаем узлы вручную.)

Обратите внимание, что нашФактический код отслеживает, если мы уже применили сортировку к рассматриваемому узлу, поэтому он не выполняется для каждого события «Expanded», но этот код не имеет отношения к этому вопросу, поэтому я для краткости опустил его.Тем не менее, вы должны добавить что-то похожее.

В любом случае, вот как вы можете выполнить сортировку по узлам ...

private void tvSymbols_Expanded(object sender, RoutedEventArgs e) {

    TreeViewItem node = e.OriginalSource as TreeViewItem;
    if(node==null) return;
    node.Items.SortDescriptions.Clear();
    node.Items.SortDescriptions.Add(new SortDescription("SomeField",      ListSortDirection.Ascending));
    node.Items.SortDescriptions.Add(new SortDescription("SomeOtherField", ListSortDirection.Descending));

}

Конечно, если кто-то все еще выяснит, почему исходный код вопроса не сделалне работай, дай знать!

Марк

...