There are two namespace , say Root.NSA and Root.NSB . In these spaces there are two classes A and B those. we have four classes Root.NSA.A , Root.NSA.B , Root.NSB.A , Root.NSB.B

Next, we create a Windows window with the following 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> 

Everything is just fine, however, I need to create the same window, with the same location of the controls, only with another xmlns:ForNameSpace , namely xmlns:ForNameSpace="clr-namespace:Root.NSB" .

Now the actual question. .XAML I have to create 2 windows and control the identity of the .cs and .XAML or is there some other solution?

PS: I mainly use {x:Static ForNameSpace:A.StaticProperty} , {x:Type ForNameSpace:A} , {x:Static ForNameSpace:B.StaticProperty} , {x:Type ForNameSpace:B} , etc.

PS2: Another clarification: All classes are inherited from Root.A and Root.B , i.e.

 class Root.NSA.A : Root.A class Root.NSA.B : Root.B class Root.NSB.A : Root.A class Root.NSB.B : Root.B 
  • And what exactly of these classes do you use? DataSource / Binding will not work? - Andrey NOP
  • @Andrew binding to static variables and types {x:Static ForNameSpace:A.staticproperty} , {x:Type ForNameSpace:A} - Dmitry Chistik
  • one
    Use MVVM and bin the values ​​on the VM. In VM and you will deliver objects of the required classes. - MihailPw
  • @ AGS17 if with {x:Static ForNameSpace:A.staticproperty} everything is clear, then what about {x:Type ForNameSpace:A} ? - Dmitry Chistik
  • one
    Statics, from her you have a lot of problems. It does not allow you to use inheritance. If the same view you can bend to two different classes, then these classes implement some kind of common interface. Get rid of statics, take out the overall functionality in the interface or (abstract) class and inherit from it. Then, when creating the view, simply pass the desired class. If your static implies the uniqueness of the instance - you just need to create these instances, for example, in the App and then just take them from there if necessary (either Singetone, or DI, or ...) - Andrey NOP

1 answer 1

Everything

 <HierarchicalDataTemplate DataType="{x:Type ForNameSpace:A}"/> <HierarchicalDataTemplate DataType="{x:Type ForNameSpace:B}"/> ... 

renamed to

 <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; } } 

also added a property to the window class

 public MyDataTemplateSelector DataTemplateSelector { get; } = new MyDataTemplateSelector(); 

and called the window

 <Window ... Name="f_MyWindow"> ... </Window> 

now in all controls where I use templates added

 ItemTemplateSelector="{Binding ElementName=f_MyWindow, Path=DataTemplateSelector}" 

and voila, no matter what the namespace the class in the ViewModel , the main thing is that the class name matches r_[имя класса] . It was still possible to check in MyDataTemplateSelector whether it is a descendant of the class Root.A or Root.B , but I didn’t have that task.

PS: the prefix r_ can be replaced by any other, there is not much difference.