Как найти ресурс в UserControl из класса DataTemplateSelector в WPF?
Я создаю свой собственный UserControl, и у меня есть два разных DataTemplates в разделе UserControl.Resources в моем XAML. Я хочу выбирать между этими двумя таблицами данных в зависимости от значения свойства объектов, отображаемых в виде списка. Я делаю это, создавая собственный класс DataTemplateSelector и переопределяя метод SelectTemplate, который должен возвращать DataTemplate, который я хочу использовать. Однако я понятия не имею, как "найти" мои шаблоны данных, которые находятся в разделе ресурсов UserControls, все примеры, которые я видел, только выбирают шаблоны данных из Window.Resources. В этом примере они выбирают текущее MainWindow, а затем используют FindResource, чтобы найти DataTemplate, как мне подобрать свой UserControl аналогичным образом?:
public override DataTemplate
SelectTemplate(object item, DependencyObject container)
{
if (item != null && item is AuctionItem)
{
AuctionItem auctionItem = item as AuctionItem;
Window window = Application.Current.MainWindow;
switch (auctionItem.SpecialFeatures)
{
case SpecialFeatures.None:
return
window.FindResource("AuctionItem_None")
as DataTemplate;
case SpecialFeatures.Color:
return
window.FindResource("AuctionItem_Color")
as DataTemplate;
}
}
return null;
}
Пример выше отсюда: ItemsControl.ItemTemplateSelector Свойство
4 ответа
Я обычно создаю экземпляр моего DataTemplateSelector из кода с помощью UserControl в качестве параметра в конструкторе DataTemplateSelector, например так:
public class MyUserControl : UserControl
{
public MyUserControl()
{
Resources["MyDataTemplateSelector"] = new MyDataTemplateSelector(this);
InitializeComponent();
}
}
public class MyDataTemplateSelector : DataTemplateSelector
{
private MyUserControl parent;
public MyDataTemplateSelector(MyUserControl parent)
{
this.parent = parent;
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
parent.DoStuff();
}
}
Не самая красивая девушка в городе, но она выполняет свою работу;)
Надеюсь это поможет!
Попробуй это:
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item != null && item is AuctionItem)
{
AuctionItem auctionItem = item as AuctionItem;
switch (auctionItem.SpecialFeatures)
{
case SpecialFeatures.None:
return
((FrameworkElement)container).FindResource("AuctionItem_None")
as DataTemplate;
case SpecialFeatures.Color:
return
((FrameworkElement)container).FindResource("AuctionItem_Color")
as DataTemplate;
}
}
return null;
}
<DataTemplate x:Key="addTemplate">
<Button Command="{Binding Path=AddCommand}">Add</Button>
</DataTemplate>
<DataTemplate x:Key="editTemplate">
<Button Command="{Binding Path=UpdateCommand}">Update</Button>
</DataTemplate>
<TemplateSelectors:AddEditTemplateSelector
AddTemplate="{StaticResource addTemplate}"
EditTemplate="{StaticResource editTemplate}"
x:Key="addEditTemplateSelector" />
Только XAML!
Решение WinRT и Windows Phone включает перемещение по визуальному дереву до тех пор, пока не будет найден родительский элемент управления:
protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container)
{
var parent = FindParent<MyParentControlType>(container as FrameworkElement);
if(parent != null)
{
if (item is Something)
return parent.Resources["TemplateForSomething"] as DataTemplate;
else if(item is SomethingElse)
return parent.Resources["TemplateForSomethingElse"] as DataTemplate;
else
// etc
}
else
{
return App.Current.Resources["SomeFallbackResource"] as DataTemplate;
}
}
public static T FindParent<T>(FrameworkElement element) where T : FrameworkElement
{
FrameworkElement parent = Windows.UI.Xaml.Media.VisualTreeHelper.GetParent(element) as FrameworkElement;
while (parent != null)
{
T correctlyTyped = parent as T;
if (correctlyTyped != null)
return correctlyTyped;
else
return FindParent<T>(parent);
}
return null;
}
Метод FindParent основан на принятом ответе здесь: Как получить ListView из ListViewItem?