1

WPF と MVVM は初めてで、ContentTemplate (または ItemTemplate、どちらも機能していません) を C# WPF プログラムの DataTemplate プロパティにバインドしようとしています。無数のビュー/ビューモデルを作成する必要がないように、「エントリ」ごとに異なる「エントリ表示タイプ」を定義する構成ファイルがあるため、これを行っています (現在、追跡する汎用エントリ ビューモデルは 1 つだけです)。クラス構造の不必要な膨張を避けるために、ラベル、データ、および表示タイプをそのままにしておくことをお勧めします)。これを機能させる方法はありますか?

これは私が試したことの1つの例です:

XAML:

<ItemsControl IsTabStop="False" ItemsSource="{Binding Path=FNEntries}"Margin="12,46,12,12">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <ContentControl ContentTemplate="{Binding Path=TypeView}" />
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

CS ((DataTemplate)TypeView と (string)PropertyName を持つエントリ ビュー モデル クラス コンストラクター内):

NodeTypeView = (DataTemplate)Application.Current.FindResource("TypeTest");

リソース XAML:

<DataTemplate x:Key="TypeTest">
<TextBlock Margin="2,6">
  <TextBlock Text="{Binding Path=PropertyName}" />
</TextBlock>

それを実行すると、何も表示されません。ただし、コンテンツ コントロールの代わりにリソース データ テンプレートのコンテンツを直接配置すると、問題なく表示されます (データ駆動型ではないことを除けば)。ヘルプ/アドバイスをいただければ幸いです。ありがとう!

4

1 に答える 1

5

私はあなたがほとんどそれを間違っていると本当に言うでしょう=)

テンプレートをViewModelに保存することは、グラフィカルオブジェクトをVMに保存するため、一般的にはお勧めできません。これは、ビュー側で行う必要があります

アイテムのタイプなどに応じて可変のDataTemplateが必要な場合は、いくつかの代替の「よりクリーンな」ソリューションを次に示します。

前提条件:すべてのテンプレートがどこかのリソースとして定義されている。

ResourceDictionaryテスト目的で、次のような場所があるとします。

<DataTemplate x:Key="Template1" />
<DataTemplate x:Key="Template2" />
<DataTemplate x:Key="Template3" />

解決策1:使用ItemTemplateSelector

(最もクリーンなソリューションimho)この問題については、使用方法を教えてくれたこの優れたチュートリアルにリダイレクトします。 理解できれば、=Dはできません。

解決策2:でコンバーターを使用するBinding

Bindingコンバーターを使用して、現在のオブジェクト自体にバインドすることにより、を少し変更してみましょう。

<DataTemplate>
      <ContentControl ContentTemplate="{Binding Converter={StaticResource MyConverter}}" />
    </DataTemplate>

コンバーターは次のようになります(注:valueここのオブジェクトはバインドされたオブジェクトです。この場合、その型を操作しているため、この例は型についても同様です)

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value.GetType() == typeof(WhateverYouWant))
        {
        return (DataTemplate)Application.Current.FindResource("OneTemplate");
        } 
        else if (value.getType() == typeof(AnotherTypeHere))
        {
        return (DataTemplate)Application.Current.FindResource("AnotherTemplate");
        }
        // other cases here...
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value; //We don't care about this!
    }
}

これはあなたのためのトリックをするでしょう

これらのソリューションはどちらも機能し、よりクリーンになると思いますが、これがの正確な目的であることに注意してくださいItemTemplateSelector。このConverterアプローチは、これらのテンプレートセレクターについて知る前に使用したものであり、現在は使用していません。

乾杯!

于 2012-09-21T21:08:00.140 に答える