C# 我可以在XAML(在.NET4框架之前)中指定泛型类型吗?

C# 我可以在XAML(在.NET4框架之前)中指定泛型类型吗?,c#,wpf,xaml,generics,C#,Wpf,Xaml,Generics,在XAML中,我可以声明一个DataTemplate,以便在显示特定类型时使用该模板。例如,此DataTemplate将使用TextBlock显示客户名称: <DataTemplate DataType="{x:Type my:Customer}"> <TextBlock Text="{Binding Name}" /> </DataTemplate> 我想知道是否有可能定义一个DataTemplate,它将在任何时候显示IList时使用。因此,

在XAML中,我可以声明一个DataTemplate,以便在显示特定类型时使用该模板。例如,此DataTemplate将使用TextBlock显示客户名称:

<DataTemplate DataType="{x:Type my:Customer}">
    <TextBlock Text="{Binding Name}" />
</DataTemplate>

我想知道是否有可能定义一个DataTemplate,它将在任何时候显示IList时使用。因此,如果ContentControl的内容是(比如)可观察集合,它将使用该模板

public class CustomerTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item,
                                                DependencyObject container)
    {
        DataTemplate template = null;
        if (item != null)
        {
            FrameworkElement element = container as FrameworkElement;
            if (element != null)
            {
                string templateName = item is ObservableCollection<MyCustomer> ?
                    "MyCustomerTemplate" : "YourCustomerTemplate";

                template = element.FindResource(templateName) as DataTemplate;
            } 
        }
        return template;
    }
}

public class MyCustomer
{
    public string CustomerName { get; set; }
}

public class YourCustomer
{
    public string CustomerName { get; set; }
}

是否可以使用{x:type}标记扩展在XAML中声明像IList这样的泛型类型?

不是现成的,否;但也有一些有进取心的开发者已经这样做了


例如,微软的迈克·希尔伯格(Mike Hillberg)在年就使用了它。谷歌当然还有其他的选择。

不是直接在XAML中,但是您可以从XAML中引用
DataTemplateSelector
来选择正确的模板

public class CustomerTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item,
                                                DependencyObject container)
    {
        DataTemplate template = null;
        if (item != null)
        {
            FrameworkElement element = container as FrameworkElement;
            if (element != null)
            {
                string templateName = item is ObservableCollection<MyCustomer> ?
                    "MyCustomerTemplate" : "YourCustomerTemplate";

                template = element.FindResource(templateName) as DataTemplate;
            } 
        }
        return template;
    }
}

public class MyCustomer
{
    public string CustomerName { get; set; }
}

public class YourCustomer
{
    public string CustomerName { get; set; }
}
公共类CustomerTemplateSelector:DataTemplateSelector
{
公共覆盖数据模板SelectTemplate(对象项,
DependencyObject(对象容器)
{
DataTemplate=null;
如果(项!=null)
{
FrameworkElement=容器作为FrameworkElement;
if(元素!=null)
{
string templateName=项是否为可观察集合?
“MyCustomerTemplate”:“YourCustomerTemplate”;
template=element.FindResource(templateName)作为DataTemplate;
} 
}
返回模板;
}
}
公共类MyCustomer
{
公共字符串CustomerName{get;set;}
}
公共类客户
{
公共字符串CustomerName{get;set;}
}
资源字典:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    >
    <DataTemplate x:Key="MyCustomerTemplate">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="150"/>
            </Grid.RowDefinitions>
            <TextBlock Text="My Customer Template"/>
            <ListBox ItemsSource="{Binding}"
                     DisplayMemberPath="CustomerName"
                     Grid.Row="1"/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="YourCustomerTemplate">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="150"/>
            </Grid.RowDefinitions>
            <TextBlock Text="Your Customer Template"/>
            <ListBox ItemsSource="{Binding}"
                     DisplayMemberPath="CustomerName"
                     Grid.Row="1"/>
        </Grid>
    </DataTemplate>
</ResourceDictionary>

窗口XAML:

<Window 
    x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" 
    Height="300" 
    Width="300"
    xmlns:local="clr-namespace:WpfApplication1"
    >
    <Grid>
        <Grid.Resources>
            <local:CustomerTemplateSelector x:Key="templateSelector"/>
        </Grid.Resources>
        <ContentControl 
            Content="{Binding}" 
            ContentTemplateSelector="{StaticResource templateSelector}" 
            />
    </Grid>
</Window>

窗口代码隐藏:

public partial class Window1
{
    public Window1()
    {
        InitializeComponent();
        ObservableCollection<MyCustomer> myCustomers
            = new ObservableCollection<MyCustomer>()
        {
            new MyCustomer(){CustomerName="Paul"},
            new MyCustomer(){CustomerName="John"},
            new MyCustomer(){CustomerName="Mary"}
        };

        ObservableCollection<YourCustomer> yourCustomers
            = new ObservableCollection<YourCustomer>()
        {
            new YourCustomer(){CustomerName="Peter"},
            new YourCustomer(){CustomerName="Chris"},
            new YourCustomer(){CustomerName="Jan"}
        };
        //DataContext = myCustomers;
        DataContext = yourCustomers;
    }
}
公共部分类窗口1
{
公共窗口1()
{
初始化组件();
可观察收集我的客户
=新的ObservableCollection()
{
new MyCustomer(){CustomerName=“Paul”},
new MyCustomer(){CustomerName=“John”},
新建MyCustomer(){CustomerName=“Mary”}
};
可观察收集您的客户
=新的ObservableCollection()
{
新建YourCustomer(){CustomerName=“Peter”},
新建YourCustomer(){CustomerName=“Chris”},
新建YourCustomer(){CustomerName=“Jan”}
};
//DataContext=myCustomers;
DataContext=您的客户;
}
}
aelij(该项目的项目协调员)还有另一个任务要做


更酷的是什么(即使它在未来的某个时候是关闭的)。。。XAML2009(XAML2006是当前版本)将在本机上支持此功能。查看此文件以获取更多信息。

您还可以将泛型类包装在指定T的派生类中

public class StringList : List<String>{}
public类StringList:List{}

使用XAML中的StringList。

完全违背了泛型的目的,但是您可以像这样定义一个从泛型派生的类,唯一的目的是能够在XAML中使用该类型

public class MyType : List<int> { }
公共类MyType:List{}
并在xaml中使用它,例如

<DataTemplate DataType={x:Type myNamespace:MyType}>


XAML 2009仅在松散的XAML文件中受支持(从.NET 4.0、WPF 4.0开始)。也就是说,Blend、Cider(VisualStudio设计器)和编译的BAML(这是嵌入式xaml编译到的内容)。。。不支持新语法。希望在未来的WPF版本中,这种情况会有所改变。请看下面的链接并投票:这对我很有用。有一个完全空的类有点奇怪,但它完成了任务。我使用此技术构建了一个通用包装器,这可能是一个更好、更简单的解决方案。我发现这比其他模板选择器教程更容易理解。谢谢您这里实际上有两个问题,第一个是DataTemplate不支持接口,第二个是Generics对于框架的最新版本,请参阅