4 using System.Collections.Generic;
6 using System.Runtime.CompilerServices;
8 using System.Windows.Controls;
9 using System.Windows.Media;
11 using SiliconStudio.Core.Extensions;
13 namespace SiliconStudio.Presentation.View
24 private readonly List<ITemplateProvider> templateProviders =
new List<ITemplateProvider>();
29 private readonly HashSet<string> templateProviderNames =
new HashSet<string>();
34 private readonly ConditionalWeakTable<object, List<string>> usedProviders =
new ConditionalWeakTable<object, List<string>>();
39 private readonly ConditionalWeakTable<object, WeakReference> lastContainers =
new ConditionalWeakTable<object, WeakReference>();
47 if (templateProvider == null)
throw new ArgumentNullException(
"templateProvider");
49 if (templateProviderNames.Contains(templateProvider.
Name))
50 throw new InvalidOperationException(
"A template provider with the same name has already been registered in this template selector.");
52 InsertTemplateProvider(templateProviders, templateProvider,
new List<ITemplateProvider>());
53 templateProviderNames.Add(templateProvider.Name);
62 if (templateProviderNames.Remove(templateProvider.
Name))
64 templateProviders.Remove(templateProvider);
73 var element = container as FrameworkElement;
75 throw new ArgumentException(
@"Container must be of type FrameworkElement",
"container");
77 var provider = FindTemplateProvider(item, container);
81 var
template = provider.Template;
91 private static void InsertTemplateProvider(List<ITemplateProvider> list,
ITemplateProvider templateProvider, List<ITemplateProvider> movedItems)
93 movedItems.Add(templateProvider);
95 int insertIndex = 1 + list.LastIndexOf(x => x.CompareTo(templateProvider) < 0);
96 list.Insert(insertIndex, templateProvider);
98 for (
int i = insertIndex + 1; i < list.Count; ++i)
100 var followingProvider = list[i];
101 if (followingProvider.CompareTo(templateProvider) < 0)
103 if (!movedItems.Contains(followingProvider))
106 InsertTemplateProvider(list, followingProvider, movedItems);
112 private ITemplateProvider FindTemplateProvider(
object item,
DependencyObject container)
114 List<string> usedProvidersForItem = usedProviders.GetOrCreateValue(item);
116 bool shouldClear =
true;
117 WeakReference lastContainer;
119 if (lastContainers.TryGetValue(item, out lastContainer) && lastContainer.IsAlive)
123 while (parent != null)
127 if (Equals(lastContainer.Target, parent))
132 parent = VisualTreeHelper.GetParent(parent);
138 usedProvidersForItem.Clear();
141 lastContainers.Remove(item);
143 var availableSelectors = templateProviders.Where(x => x.Match(item)).ToList();
145 ITemplateProvider result = availableSelectors.FirstOrDefault(x => !usedProvidersForItem.Contains(x.Name));
149 usedProvidersForItem.Add(result.Name);
150 lastContainers.Add(item,
new WeakReference(container));
override DataTemplate SelectTemplate(object item, DependencyObject container)
string Name
Gets an identifier name for this instance of ITemplateProvider.
void UnregisterTemplateProvider(ITemplateProvider templateProvider)
Unregisters the given template into the static TemplateProviderSelector.
An interface for a class that can provide a template for a given object that matches some prerequisit...
void RegisterTemplateProvider(ITemplateProvider templateProvider)
Registers the given template into the static TemplateProviderSelector.
An implementation of DataTemplateSelector that can select a template from a set of statically registe...