XAMLでは、特定の型が表示されるたびにテンプレートが使用されるように、DataTemplateを宣言できます。たとえば、このDataTemplateはTextBlockを使用して顧客の名前を表示します。
<DataTemplate DataType="{x:Type my:Customer}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
IList <Customer>が表示されるときにいつでも使用されるDataTemplateを定義できるかどうか疑問に思っています。したがって、ContentControlのコンテンツが、たとえばObservableCollection <Customer>である場合、そのテンプレートを使用します。
{x:Type}マークアップ拡張機能を使用して、XAMLでIListのようなジェネリック型を宣言することは可能ですか?
箱から出していない、いいえ。しかし、そうしている進取の気性のある開発者がいます。
たとえば、MicrosoftのMike Hillbergは この投稿 でそれを試しました。 Googleにはもちろん他にもあります。
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; }
}
リソースディクショナリ:
<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;
}
}
Tを指定する派生クラスでジェネリッククラスをラップすることもできます
public class StringList : List<String>{}
xAMLのStringListを使用します。
aelij( WPF Contrib プロジェクトのプロジェクトコーディネーター)には、別の way があります。
さらにクールなのは(将来的にはいつかはオフになりますが)... XAML 2009(XAML 2006が現在のバージョンです)がこれをネイティブにサポートすることです。詳細については、こちらをご覧ください PDC 2008セッション .
.netフレームワークの再送信バージョンでは、これを行うことができます。
XAMLドキュメントのジェネリック を確認してください。 x:TypeArguments
;を使用する必要があります。いくつかの制限があるため、最初にドキュメントをお読みください。
Stackoverflowの XAMLでジェネリック型引数を指定する方法 の質問も参照してください
ジェネリックの目的はかなり打ち負かされますが、XAMLでそのタイプを使用できるという唯一の目的で、ジェネリックから派生したクラスを定義できます。
public class MyType : List<int> { }
そして、xamlで使用します。お気に入り
<DataTemplate DataType={x:Type myNamespace:MyType}>