Могу ли я указать универсальный тип в XAML (до .NET 4 Framework)?

В XAML я могу объявить DataTemplate, чтобы шаблон использовался всякий раз, когда отображается определенный тип. Например, этот DataTemplate будет использовать TextBlock для отображения имени клиента:

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

Мне интересно, можно ли определить DataTemplate, который будет использоваться каждый раз, когда отображается IList <Customer>. Итак, если ContentControl Content является, скажем, ObservableCollection <Customer>, он будет использовать этот шаблон.

Можно ли объявить универсальный тип, такой как IList, в XAML с помощью расширения разметки {x: Type}?

На самом деле у вас есть 2 проблемы: во-первых, DataTemplate не поддерживает интерфейсы, а второй - универсальные.

MikeT 16.07.2014 15:23

Для последних версий фреймворка см. stackoverflow.com/questions/7573712/…

Ian Ringrose 12.09.2015 20:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
73
2
41 887
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Не из коробки, нет; но есть предприимчивые разработчики, которые это сделали.

Майк Хиллберг из Microsoft, например, играл с ним в эта почта. У Google, конечно, есть и другие.

Не непосредственно в XAML, однако вы можете ссылаться на DataTemplateSelector из XAML, чтобы выбрать правильный шаблон.

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

Возможно лучшее и простое решение

Nerd in Training 23.10.2012 17:10

Я считаю, что это легче понять, чем другие руководства по выбору шаблонов. Спасибо

Jack Frost 02.05.2018 14:27

У aelij (координатора проекта WPF Contrib) есть еще один путь для этого.

Что еще круче (даже если это когда-нибудь в будущем) ... то, что XAML 2009 (XAML 2006 - текущая версия) будет поддерживать это изначально. Ознакомьтесь с этим Сессия PDC 2008, чтобы узнать об этом и многое другое.

XAML 2009 поддерживается только (начиная с .NET 4.0, WPF 4.0) в свободных файлах xaml. То есть Blend, Cider (дизайнер Visual Studio) и скомпилированный BAML (в который компилируется ваш встроенный xaml) ... не поддерживают новый синтаксис. Надеюсь, это изменится в будущей версии WPF. Смотрите следующую ссылку и голосуйте: dotnet.uservoice.com/forums/40583-wpf-feature-suggestions/…

cplotts 25.09.2010 01:00

Вы также можете заключить свой универсальный класс в производный класс, который определяет T

public class StringList : List<String>{}

и используйте StringList из XAML.

Это сработало для меня. Немного странно иметь полностью пустой класс, но он выполняет свою работу.

T.J.Kjaer 24.11.2010 16:47

Я создал общую оболочку, используя эту технику в stackoverflow.com/a/33827448/11635

Ruben Bartelink 20.11.2015 16:09

Совершенно противоречит цели универсального, но вы можете определить класс, производный от универсального, подобным образом, с единственной целью - иметь возможность использовать этот тип в XAML.

public class MyType : List<int> { }

И используйте его в xaml, например. нравиться

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

Другие вопросы по теме