xmlns в коде для класса

206
20 апреля 2017, 14:12

Есть две 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
Answer 1

Все

<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_ можно заменить на любой другой, особой разницы нет.

READ ALSO
Копирование файла?

Копирование файла?

https://pastebincom/bYKcyn8n

273
Наследоваие UserControl

Наследоваие UserControl

Имеются UserControl'ы, они все наследуются от UserControlИ как сделать чтоб они наследовались от AbstractClass, а сам AbstractClass от UserControl

245
C# Создание классов

C# Создание классов

Ребят, приветУ меня вопрос насчёт классов C#

246
Как передвигать панель вместе с label?

Как передвигать панель вместе с label?

На форму вешаю компонент "Panel" кидаю на панель label

401