Czy mogę podać typ generyczny w XAML (pre.NET 4)?

W XAML mogę zadeklarować DataTemplate tak, że szablon jest używany zawsze, gdy wyświetlany jest określony typ. Na przykład, ta tablica danych użyje blokady tekstowej do wyświetlenia nazwy klienta:

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

Zastanawiam się, czy jest możliwe zdefiniowanie Datatematplate, który będzie używany za każdym razem, gdy wyświetli się IList. Jeśli więc zawartość Contentcontroll jest, powiedzmy, Obserwowalną kolekcją , użyje tego szablonu.

Czy Można zadeklarować rodzaj ogólny jak IList w XAML używając rozszerzenia znaczników {X:Type}?

Author: Askolein, 2008-10-09

6 answers

Nie po wyjęciu z pudełka, nie; ale są przedsiębiorczy deweloperzy, którzy to zrobili.

Mike Hillberg z Microsoftu bawił się tym na przykład w tym poście . Google ma oczywiście inne.

 24
Author: ageektrapped,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-09 01:26:00

Nie bezpośrednio w XAML, jednak możesz odwołać się do {[4] } z XAML, aby wybrać odpowiedni szablon.

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; }
}

Słownik zasobów:

<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>

Okno 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>

Kod okna za:

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;
    }
}
 30
Author: Ian Oakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 14:55:06

Możesz również zawinąć swoją klasę generyczną w klasę pochodną, która określa T

public class StringList : List<String>{}

I użyj StringList z XAML.

 21
Author: Claudiu Mihaila,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-28 23:09:45

Aelij (koordynator projektu WPF Contrib) ma inny sposób, aby to zrobić.

Co jest jeszcze fajniejsze (mimo że w przyszłości jest wyłączone)... czy XAML 2009 (XAML 2006 jest obecna wersja) będzie wspierać to natywnie. Sprawdź tę PDC 2008 sesję aby uzyskać informacje na ten temat i więcej.

 7
Author: cplotts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-04 01:28:37

Uważam, że w wersji. NET framework można to zrobić.

Sprawdź Generyki w dokumentacji XAML . Musisz użyć x:TypeArguments; istnieją pewne ograniczenia, więc najpierw przeczytaj dokument.

Zobacz także Jak podać argument generic type W pytaniu XAML na Stackoverflow

 0
Author: Ian Ringrose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:14

Całkiem nie pasuje do celu generycznego, ale można zdefiniować klasę, która wywodzi się z generycznego w ten sposób, tylko po to, aby móc używać tego typu w XAML.

public class MyType : List<int> { }

I używać go w xaml np. like

<DataTemplate DataType={x:Type myNamespace:MyType}>
 0
Author: Mike de Klerk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-11 10:01:42