1

私は次の設定をしています:

<ListBox ItemSource="{Binding Targets}">
    <ListBox.ItemTemplate>
        <DataTemplate>
          <view:ViewName />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

私が達成しようとしているのは、の内のプロパティに基づいて、実行時に使用するビューを動的に決定することDataContextですListBox<view:ViewName>簡単に言うと、適切なビューを返すデータバインディングに置き換えたいと思います。

MEFを使用して、必要に応じてアイテムを表示するためのカスタムビューを提供する必要がある可能性のあるアプリのプラグインを提供しています。設計時には、考えられるすべてのビュータイプ(DLLから動的にロードされる可能性があります)がわからないため、単純なビュータイプではわかりDataTemplateSelectorません。

私は解決策を研究しましたが、空っぽになりました。

4

2 に答える 2

2

バインドされた値に基づいてテンプレートを変更する必要があるため、を使用してのDataTriggerを決定できますContentTemplateListBoxItem

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="ContentTemplate" Value="{StaticResource DefaultTemplate}"/>
    <Style.Triggers>
        <DataTrigger Property="{Binding SomeProperty}" Value="A">
            <Setter Property="ContentTemplate" Value="{StaticResource TemplateA}"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

DataTemplateSelectorバインドされたプロパティが変更された場合は再評価されますが、変更されない場合は再評価されるため、これを使用するよりも優れていると思いますDataTemplateSelector

オブジェクトタイプに基づいてテンプレートを変更する場合は、Implicitを使用できますDataTemplates。これらはDataTemplates、を定義しますが、を定義するものDataTypeではなくx:Key、WPFが指定されたタイプのオブジェクトを描画しようとするたびに使用されます。

たとえば、このテンプレートを<X.Resources>どこかで定義した場合

<DataTemplate DataType="{x:Type models:ActionA}">
    <views:ActionAView />
</DataTemplate>

次に、ModelオブジェクトをUIに直接挿入すると、WPFは指定したテンプレートを使用してオブジェクトを描画します。

<ContentControl Content="{Binding SomeIActionObject}" />

<ItemsControl ItemsSource="{Binding CollectionOfIActionObjects}" />

アップデート

MEFを使用してインポートされる追加のテンプレートを使用してユーザーがモジュールを作成できるようにすることを説明したので、その場合は、内の一致するテンプレートを検索するIValueConverterを使用する方がよいでしょう。Application.Resources

たとえば、バインドされた値がに等しい場合"A"、コンバータはApplication.Resourcesという名前のテンプレートを検索し、"TemplateA"それをバインディングに返すことができます。

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="ContentTemplate" 
            Value="{Binding SomeProperty, 
                Converter={StaticResource MyTemplateConverter}}"/>
</Style>
于 2013-03-26T19:10:00.703 に答える
1

この投稿DataTemplateManagerからの使用あなたは次のようなことをすることができます:

DataTemplateManager.RegisterDataTemplate<ViewModelType1, ViewType1>();
DataTemplateManager.RegisterDataTemplate<ViewModelType2, ViewType2>();
DataTemplateManager.RegisterDataTemplate<ViewModelType3, ViewType3>();

ItemTemplate次に、リストボックスからを削除します。

<ListBox ItemSource="{Binding Targets}"/>

ListBox ViewModelでは、次のことができます。

public void AddTargets()
{
    Targets.Add(new ViewModelType1());
    Targets.Add(new ViewModelType2());
    Targets.Add(new ViewModelType3());
}

次に、それぞれDataTemplateがWPFによって自動的に使用され、対応する各ViewModelがレンダリングされます。

DataTemplateManager.RegisterDataTemplate()また、リストボックスを表示する前であればいつでも呼び出すことができるため、理論的にはMEFパーツをロードするときに呼び出すことができます。

編集:

コメントに基づいて、ContentPresenterを使用して単一のDataTemplateを作成し、ViewModelのプロパティに従って選択したビューを表示できます。

<DataTemplate DataType="{x:Type local:TargetViewModel}">
    <ContentPresenter x:Name="MainContentPresenter" Content="{Binding}" ContentTemplate="{Binding YourProperty, Converter=SomeConverter}"/>

また、SomeConverter内では、投稿で示されているのと同じ手法を使用して、DataTemplateを動的に生成する必要があります。

于 2013-03-26T18:34:55.903 に答える