0

この質問は、 「HierarchicalDataTemplateのDataType属性でジェネリック型を参照する方法」に対するこの回答と強く関連しています。

私はその答えの基本的な考え方に従い、このデータ構造を作成しました。

<!-- for DictItemVM<string, Remote.Address> which is a viewmodel for a KeyValuePair<...> -->
<x:Array Type="{x:Type sys:Type}"
         x:Key="KVParamsStringToRemoteAddress"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         xmlns:remote="clr-namespace:Remote"
         xmlns:mvvm="clr-namespace:MVVM">
    <x:Type TypeName="sys:String" />
    <mvvm:GenericType BaseType="{x:Type TypeName=remote:Address}"/>
</x:Array>

<mvvm:GenericType xmlns:mvvm="clr-namespace:MVVM"
                  BaseType="{x:Type TypeName=mvvm:DictItemVM`2}"
                  InnerTypes="{StaticResource KVParamsStringToRemoteAddress}"
                  x:Key="DictItemVMOfStringToRemoteAddress"/>

DictItemVM<T,U>はのビューモデルであり、KeyValuePair<...>BaseVMから派生しています。BaseVMにはDa​​taTemplateビューがありますが、のために作成しようとしていますDictItemVM<string, Remote.Address>
Remote.Addressは、複合値タイプです(パスおよびアクセス情報を格納します)。Remote.Addressには、独自のDataTemplateビューがあります。
StaticResource "DictItemVMOfStringToRemoteAddress"ができたので、これを使用してDataTemplateを指定します。

<DataTemplate x:Key="TestKey" DataType="{StaticResource DictItemVMOfStringToRemoteAddress}">
    <StackPanel>
        <Label Content="UniqueName" />
        <TextBox Text="{Binding UniqueName}" />
        <Label Content="Key"/>
        <TextBox Text="{Binding Key, Mode=OneWay}" IsEnabled="False" />
        <Label Content="Value"/>
        <ContentControl Content="{Binding Value, Mode=OneWay}" />
    </StackPanel>
</DataTemplate>

これで、このDataTemplateをビューとして使用する必要がありますが、代わりにBaseVMのビューが表示されています。
誰かが私にこれについてのヒントをくれますか?

[編集:2010-08-09]
私が試したいくつかのこと:

x:Arrayの定義では、 基本的には、に置き換え
<mvvm:GenericType BaseType="{x:Type TypeName=remote:Address}"/>
ました。違いはありません。
<x:Type TypeName="remote:Address"/>

また、次のように(StaticResourceにリンクする代わりに)タグの間にDataTypeを作成しようとしました。

<DataTemplate x:Key="TestKey">
    <DataTemplate.DataType>
        <Binding>
            <Binding.Source>
                <mvvm:GenericType 
                  BaseType="{x:Type TypeName=mvvm:DictItemVM`2}">
                    <mvvm:GenericType.InnerTypes>
                        <x:Type TypeName="sys:String" />
                        <x:Type TypeName="remote:Address"/>
                    </mvvm:GenericType.InnerTypes>
                </mvvm:GenericType>
            </Binding.Source>
        </Binding>
    </DataTemplate.DataType>

GenericType.InnerTypes内のx:Arrayを使用して、または使用せずに試してみましたが、どちらもこのエラーが発生しました。

次のような静的プロパティから型を渡そうとしました:
DataType="{x:Static mvvm:StaticTypes.DictItemVMOfStringToRemoteAddress}"
そしてこのように:
DataType="{Binding Path={x:Static mvvm:StaticTypes.DictItemVMOfStringToRemoteAddress}}"
違いはありません。

奇妙なことに、この特定のDataTemplateにはx:Key、たとえば次のような通常の型を指すxamlリソースファイル内の他のすべてとは対照的に、何らかの値が必要ですDataType="{x:Type mvvm:EffectVM}"。x:Keyを削除すると、このエラーが発生します。

4

1 に答える 1

1

私は解決策を見つけましたが、その解決策は本当に満足のいくものではありません。

XAMLで、表示するタイプごとにDataTemplateを作成し、KeyValuePair<T,U>それに固有のx:Keyを指定します。

<DataTemplate x:Key="DictItemOfStringAndAddressVM">
    <!-- ... -->
</DataTemplate>

次に、分離コードで、DataTemplateSelectorを作成し、SelectTemplateをオーバーライドします。

public class GenericDataTemplateSelector : System.Windows.Controls.DataTemplateSelector
{
    public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if ((element != null) && (item != null))
        {
            if (item is DictItemVM<string, Remote.Address>)
            {
                return element.FindResource("DictItemOfStringAndAddressVM") as DataTemplate;
            }
            else if(item is SomeOtherComplexType)
            {
                // ...
            }
            else return base.SelectTemplate(item, container);
        }
        return null;
    }
}

再びXAMLで、このクラスをリソースとして宣言します。

<mvvm:GenericDataTemplateSelector x:Key="GenDataTempSelect"/>

最後に、(私の場合)ContentControlに、プロパティを追加します。

ContentTemplateSelector="{StaticResource GenDataTempSelect}"

-

短所:

  • 新しいDataTemplateを作成するときは、2つの場所でコードを変更する必要があります。
  • 各ContentControl、ListView、...は、適切なプロパティを設定する必要があります。
  • WPFでジェネリック型を参照する方法の質問には実際には答えません!

利点:

  • 新しいタイプの構造や複雑さを簡単に追加できます(C#がWPFよりも優れているすべての利点を享受しています...)
  • 上記のソリューションで必要となるような、WPFでの複雑なネストされた型の説明はありません。
于 2010-08-11T08:36:24.660 に答える