Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何在DataTemplate的DataType属性中引用泛型类型的特定实现?_.net_Wpf_Generics_Xaml_Markup Extensions - Fatal编程技术网

.net 如何在DataTemplate的DataType属性中引用泛型类型的特定实现?

.net 如何在DataTemplate的DataType属性中引用泛型类型的特定实现?,.net,wpf,generics,xaml,markup-extensions,.net,Wpf,Generics,Xaml,Markup Extensions,此问题与“”的此答案密切相关 我遵循该答案的基本思想,创建了以下数据结构: <!-- for DictItemVM<string, Remote.Address> which is a viewmodel for a KeyValuePair<...> --> <x:Array Type="{x:Type sys:Type}" x:Key="KVParamsStringToRemoteAddress" xmlns:x=

此问题与“”的此答案密切相关

我遵循该答案的基本思想,创建了以下数据结构:

<!-- 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
KeyValuePair
的视图模型,从BaseVM派生而来。BaseVM有一个DataTemplate视图,但我正在努力为
DictItemVM

地址是一种复杂的值类型(存储路径和访问信息)。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定义中,我替换了



因为基本上就是这样-没有区别

还尝试在标记之间创建数据类型(而不是链接到StaticResource),如下所示:

<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.dictItemVMOfstringStoreRemoteAddress}”

就像这样:
DataType=“{Binding Path={x:Static mvvm:StaticTypes.DictItemVMOfStringToRemoteAddress}”

没有区别


奇怪的是,这个特定的数据模板需要有一些
x:Key
值,而xaml资源文件中的所有其他值都指向常规类型,例如:
DataType=“{x:type mvvm:EffectVM}”
。如果我删除了x:Key,就会出现错误。

我找到了一个解决方案,尽管这个解决方案并不令人满意

在XAML中,为要显示的每种类型的
KeyValuePair
创建一个数据模板,并为其指定一些唯一的x:Key:

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

缺点:

  • 创建新数据模板时,必须在两个位置更改代码
  • 每个ContentControl、ListView。。。必须设置它的相应属性
  • 并没有真正回答如何在WPF中引用泛型类型的问题
优点:

  • 易于添加任何结构或复杂性的新类型(享受C#相对于WPF的所有好处…)
  • 在WPF中没有复杂的嵌套类型描述,正如上面的解决方案所要求的那样
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;
    }
}
<mvvm:GenericDataTemplateSelector x:Key="GenDataTempSelect"/>
ContentTemplateSelector="{StaticResource GenDataTempSelect}"