Есть две namespace, Допустим Root.NSA и Root.NSB. В этих пространствах есть по два класса A и B. т.е. имеем четыре класса Root.NSA.A, Root.NSA.B, Root.NSB.A, Root.NSB.B.
Далее мы создаем окно Windows со следующим XAML:
<Window x:Class="PhoneStructure.ObjectShemeEdit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ForNameSpace="clr-namespace:Root.NSA">
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type ForNameSpace:A}">
...
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type ForNameSpace:B}">
...
</HierarchicalDataTemplate>
</Window.Resources>
<TreeView ItemsSource="..."><!-- Элементы это экземпляры класса A и B, Темплейты подгружаются из ресурсов выше -->
</TreeView>
</Window>
Все просто отлично, однако, мне необходимо создать такое же окно, с таким же расположением контролов, только с другим xmlns:ForNameSpace, а именно xmlns:ForNameSpace="clr-namespace:Root.NSB".
Теперь собственно вопрос. Мне придется создавать 2 окна и контролировать идентичность кода .cs и .XAML или есть какое - то другое решение?
PS: использую в основном {x:Static ForNameSpace:A.StaticProperty}, {x:Type ForNameSpace:A}, {x:Static ForNameSpace:B.StaticProperty}, {x:Type ForNameSpace:B} и т.д.
PS2: Еще уточнение: Все классы наследуются от Root.A и Root.B, т.е.
class Root.NSA.A : Root.A
class Root.NSA.B : Root.B
class Root.NSB.A : Root.A
class Root.NSB.B : Root.B
Все
<HierarchicalDataTemplate DataType="{x:Type ForNameSpace:A}"/>
<HierarchicalDataTemplate DataType="{x:Type ForNameSpace:B}"/>
...
переименовал в
<HierarchicalDataTemplate x:Key="r_A"/>
<HierarchicalDataTemplate x:Key="r_B"/>
...
добавил DataTemplateSelector
public class MyDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
string key = "r_" + item.GetType().Name;
DependencyObject root = null;
DependencyObject next = container;
while (next != null)
{
root = next;
next = System.Windows.Media.VisualTreeHelper.GetParent(root);
}
if ((root as FrameworkElement).Resources.Contains(key))
return (root as FrameworkElement).Resources[key] as DataTemplate;
return null;
}
}
также в класс окна добавил свойство
public MyDataTemplateSelector DataTemplateSelector { get; } = new MyDataTemplateSelector();
и обозвал окно
<Window ...
Name="f_MyWindow">
...
</Window>
теперь во всех контролах, где использую шаблоны добавил
ItemTemplateSelector="{Binding ElementName=f_MyWindow, Path=DataTemplateSelector}"
и вуаля, неважно какой namespace у класса во ViewModel, главное чтобы имя класса совпадало с r_[имя класса]. Можно еще было в MyDataTemplateSelector проверить является ли потомком класса Root.A или Root.B, но у меня не стояла в этом задача.
ЗЫ: префикс r_ можно заменить на любой другой, особой разницы нет.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей