75

XAML では、DataTemplate を宣言して、特定の型が表示されるたびにテンプレートが使用されるようにすることができます。たとえば、この DataTemplate は TextBlock を使用して顧客の名前を表示します。

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

IList<Customer> が表示されるたびに使用される DataTemplate を定義できるかどうか疑問に思っています。したがって、ContentControl の Content が ObservableCollection<Customer> の場合、そのテンプレートが使用されます。

{x:Type} マークアップ拡張機能を使用して、XAML で IList のようなジェネリック型を宣言することは可能ですか?

4

5 に答える 5

32

XAML で直接ではありませんが、DataTemplateSelectorXAML から を参照して正しいテンプレートを選択できます。

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;
    }
}
于 2008-10-09T10:39:12.230 に答える
24

すぐに使えるわけではありません。しかし、そうしている進取の気性に富んだ開発者がそこにいます。

たとえば、Microsoft の Mike Hillberg は、この投稿でそれを試しました。もちろん、Googleには他にもあります。

于 2008-10-09T01:26:00.490 に答える
21

T を指定する派生クラスでジェネリック クラスをラップすることもできます。

public class StringList : List<String>{}

XAML から StringList を使用します。

于 2010-10-28T23:09:45.407 に答える
7

aelij ( WPF Contribプロジェクトのプロジェクト コーディネーター) には別の方法があります。

さらに優れているのは (将来的にはオフになりますが) ... XAML 2009 (XAML 2006 が現在のバージョン) がこれをネイティブにサポートすることです。詳細については、このPDC 2008 セッションをご覧ください。

于 2008-11-04T01:28:37.830 に答える