Похоже, что мой первоначальный ответ был вызван неправильным пониманием вопроса, и требование заключается не в селекторе шаблонов данных, а в том, как параметризовать свойство, к которому привязывается привязка, поэтому вы можете использовать тот же шаблон для двух разных свойств.
Быстрый ответ: Это не тот способ, которым XAML предназначен для использования. Вы не можете параметризовать свойство Path
объекта Binding
. Обычным решением является написать один шаблон для каждого случая. Было бы неплохо, если бы вы могли указать, какое свойство/поле должно отображать DataGridTemplateColumn
, через свойство или DisplayMemberPath
, а затем передать это значение шаблону - но это не работает.
I found a likely-looking workaround here, но я не уверен, что ROI на нем будет складываться хорошо относительно копирования и вставки DataTemplate
и продолжения вашей жизни.
Если шаблоны достаточно сложна для обслуживания, чтобы быть беспокойство, вы можете работать вокруг, что вот так:
XAML ресурсов:
<DataTemplate x:Key="RedBaseTemplate">
<Border BorderBrush="Green" BorderThickness="2" Margin="1">
<Label x:Name="Text" Background="Red" Content="{Binding}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="GreenBaseTemplate">
<Border BorderBrush="Red" BorderThickness="2" Margin="1">
<Label x:Name="Text" Background="Green" Content="{Binding}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="RedTemplateA">
<ContentControl
Content="{Binding A}"
ContentTemplate="{StaticResource RedBaseTemplate}"
/>
</DataTemplate>
<DataTemplate x:Key="RedTemplateB">
<ContentControl
Content="{Binding B}"
ContentTemplate="{StaticResource RedBaseTemplate}"
/>
</DataTemplate>
<DataTemplate x:Key="GreenTemplateA">
<ContentControl
Content="{Binding A}"
ContentTemplate="{StaticResource GreenBaseTemplate}"
/>
</DataTemplate>
<DataTemplate x:Key="GreenTemplateB">
<ContentControl
Content="{Binding B}"
ContentTemplate="{StaticResource GreenBaseTemplate}"
/>
</DataTemplate>
оригинальный ответ
Это общий шаблон: вы хотите, чтобы несколько экземпляров одного и того же DataTemplateSelector
(или конвертер значений, довольно часто), но с разными параметрами. Решение состоит в том, чтобы получить от MarkupExtension
, поэтому вы можете создать экземпляр объекта в точке использования с его собственными уникальными параметрами, а не создавать один общий экземпляр где-то еще в качестве ресурса. В этом случае DataTemplateSelector
- это класс, а не интерфейс, поэтому вы не можете получить свой селектор от MarkupExtension
. Вместо этого вы пишете быстрый MarkupExtension
, который возвращает ваш селектор.
Я хотел сам пройти шаблоны до RedGreenTemplateSelectorExtension
, используя StaticResource
или DynamicResource
в XAML, но синтаксическому анализатору XAML не понравилась эта идея. Но это работает достаточно хорошо.
public class RedGreenTemplateSelectorExtension : MarkupExtension
{
public Object RedTemplateKey { get; set; }
public Object GreenTemplateKey { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
var redTemplate = new StaticResourceExtension(RedTemplateKey)
.ProvideValue(serviceProvider) as DataTemplate;
var greenTemplate = new StaticResourceExtension(GreenTemplateKey)
.ProvideValue(serviceProvider) as DataTemplate;
return new RedGreenTemplateSelector() {
RedTemplate = redTemplate,
GreenTemplate = greenTemplate
};
}
}
public class RedGreenTemplateSelector : DataTemplateSelector
{
public DataTemplate RedTemplate { get; set; }
public DataTemplate GreenTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is RedItem)
return RedTemplate;
else if (item is GreenItem)
return GreenTemplate;
else
return base.SelectTemplate(item, container);
}
}
XAML
<StackPanel>
<ContentControl
ContentTemplateSelector="{local:RedGreenTemplateSelector RedTemplateKey=RedTemplate, GreenTemplateKey=GreenTemplate}"
>
<local:RedItem/>
</ContentControl>
<ContentControl
ContentTemplateSelector="{local:RedGreenTemplateSelector RedTemplateKey=RedTemplate, GreenTemplateKey=GreenTemplate}"
>
<local:GreenItem/>
</ContentControl>
</StackPanel>
P.S. StaticResource
и Binding
- это два совершенно разных класса, которые делают разные вещи. Люди злоупотребляют «привязкой» к «присвоению». Это не. Здесь вы не используете никаких привязок.
Спасибо, Эдвард за ваш ответ. Я просто хотел бы прояснить вопрос привязки к полям Name1 и Name2 из DataGridTemplateColumn. – Jupirage
Прошу прощения, я неправильно понял ваши потребности. Это невозможно. –
В Интернете я нашел ключ. Внутри SelectTemplate, в тот момент, когда DataTemplate собирается вернуться, мы можем изменить привязки шаблона с помощью FrameworkElementFactory, чтобы назначить правильный Путь: «Name1» или «Name2». Как factory.SetBinding (ContentPresenter.ContentProperty, новое связывание (путь)); Я еще не совсем уверен. Что бы вы сказали? – Jupirage