3

これはかなり複雑です。うまくいけば、誰かが私を助けてくれるように、これを十分に明確にすることができます。Manager と呼べるオブジェクトがあります。Manager には、彼が管理する人々のコレクションがあり、人々はすべて IPerson を実装していますが、さまざまな種類の人々がさまざまなプロパティを持っています。このマネージャーをツリーで表示し、マネージャー ノードの下に、彼が管理しているすべてのプロジェクトを表示したいと考えています。これは、彼が管理する人々から判断できます。

したがって、コンバーターを使用して人をプロジェクトのリストに変換する計画です。XAML は次のとおりです。

<HierarchicalDataTemplate DataType="{x:Type ui:Manager}">
   <TextBlock Text="{Binding Path=Name}"/>
    <HierarchicalDataTemplate.ItemTemplate>
        <DataTemplate>
                    <TextBlock Text="{Binding}"/>
        </DataTemplate>
    </HierarchicalDataTemplate.ItemTemplate>
    <HierarchicalDataTemplate.ItemsSource>
        <Binding Path="People">
            <Binding.Converter>
                <configUtil:ProjectListConverter/>
            </Binding.Converter>
        </Binding>
    </HierarchicalDataTemplate.ItemsSource>
</HierarchicalDataTemplate>

私の Person クラスは INotifyPropertyChanged を実装し、人々を保持するリストは INotifyCollectionChanged を実装します。このコードは、ツリービューの ItemsSource を設定するとうまく機能し、マネージャーはプロジェクトのリストと共に表示されます。

ただし、人のリストに新しい人を追加しても、TreeView は更新されません。デバッグすると、追加アクションと追加された項目で CollectionChanged が起動していることがわかります。また、CollectionChanged イベントは null ではないため、UI が監視していることがわかります。ただし、アイテムが追加されたときにコンバーターは実行されません。

IPerson オブジェクトを保持する List の Add メソッドを次に示します。

public void Add(T item)
{
    list.Add(item);
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}

どういうわけかデータバインディングを壊していますか?

他にどのようなことを確認できますか?

コンバーターは、人物リストの各アイテムを見て、彼らが取り組んでいるプロジェクトを把握し、プロジェクト名を出力リストに追加します。

4

1 に答える 1

2

コンバーターは、コレクションを格納するプロパティに適用されます。したがって、コレクション インスタンス自体が変更された場合にのみ呼び出されます (コレクション内のアイテムが変更された場合ではありません)。これを回避する 1 つの方法は、コレクションを更新するときにコレクションを無効にすることです。

コレクション プロパティを無効にしてコンバータ コードを再度実行させる最も簡単な方法は、コレクションを削除しnullて再割り当てすることです。別の方法は、BindingExpression(経由でBindingOperations) を取得して を呼び出すことUpdateTargetです。最後に、代わりにCollectionView(またはそのサブクラス) にバインドして呼び出すことができRefreshます。

そして、本当に問題をきれいに修正したい場合ICollectionViewは、フィルタリングを行い、必要に応じてイベントを発生させる独自の実装にバインドできます。

于 2009-04-01T18:06:07.180 に答える