Есть две 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_
можно заменить на любой другой, особой разницы нет.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Имеются UserControl'ы, они все наследуются от UserControlИ как сделать чтоб они наследовались от AbstractClass, а сам AbstractClass от UserControl