7

データ テンプレート内で CollectionViewSource を明示的に使用することは可能ですか? 通常は CollectionViewSource をテンプレートと一緒にリソースに配置しますが、コレクションビューソースの「ソース」はツリーのこのレベルの DataContext のプロパティであるため、モデルではそれが許可されません。つまり、インスタンスが必要です。このレベルで。リソースのルートに配置すると、インスタンスが 1 つしかないことになります。また、これらのアイテムは階層をこれほど下に降りるまで存在せず、すべての兄弟がこのプロパティを持っているわけではないため、外側のレベルでグループ化を単純に使用することはできません。したがって、DataTemplate 内で CollectionViewSource をインスタンス化することは論理的に理にかなっています (この例では HierarchicalDataTemplate ですが、それは無関係です)。

具体的には、この特定のノード レベルで特定の並べ替えを許可しようとしています。他の唯一の選択肢は、ViewModel 自体をソートすることですが、ソートをサポートしていない ObservableCollections を使用しているため、これは面倒です。実際、このトピックで見たすべての記事では、CollectionViewSource を正確に使用する必要があると述べているため、この質問があります。

たとえば、これはうまくいきます…</p>

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

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

</HierarchicalDataTemplate>

しかし、これはそうではありません…</p>

<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 をデータ テンプレートと同じレベルに配置することはできません。テンプレートごとに 1 つのインスタンスが必要なためです。それぞれに独自のアイテム セットがあるためです (ただし、それらはすべて並べ替え基準を共有します)。

M

4

1 に答える 1

4

わかりました...これはまさに私がやりたかったことではありませんが、結果はまったく同じで、誰もコメントもせず、答えもしなかったので、これを1つにしました.

これを行う必要がある最初の理由は、ノード固有のソートを行うことでした。CollectionViewSource を機能させることはできませんでしたが、並べ替えをノードに直接適用することはできました。秘訣は、ノードの作成時、またはノードが展開されたときのように行うことです (バインディングを使用しているため、手動でノードを作成しません)。

問題のノードに並べ替えが既に適用されているかどうかを実際のコードが追跡するため、「拡張」イベントごとに実行されませんが、そのコードはこの質問とは無関係であるため、簡潔にするために省略しました。それでも、似たようなものを追加する必要があります。

とにかく、ノードごとのソートを行う方法は次のとおりです...

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

}

もちろん、元の質問のコードが機能しなかった理由を誰かがまだ理解している場合は、知っておきましょう!

マーク

于 2010-10-21T08:20:18.603 に答える