0

Есть TreeView (каталог разнотипных объектов) и TabControl, который будет в себе хранить формы.

<!-- Представление каталога -->
<GroupBox Header="Catalog">
    <TreeView FontSize="14pt" ItemsSource="{Binding RootNodes}">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type vm:NodeViewModel}"
                                        ItemsSource="{Binding Subnodes}">
                <StackPanel Orientation="Horizontal">
                    <StackPanel.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Добавить" Command="{Binding AddChildCommand}" />
                            <MenuItem Header="Удалить" Command="{Binding RemoveChildCommand}" />
                        </ContextMenu>
                    </StackPanel.ContextMenu>
                    <TextBlock Text="{Binding Name}" />
                </StackPanel>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type vm:EquipmentNodeViewModel}"
                                        ItemsSource="{Binding Subnodes}">
                <StackPanel Orientation="Horizontal">
                    <StackPanel.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Добавить" Command="{Binding AddChildCommand}" />
                            <MenuItem Header="Удалить" Command="{Binding RemoveChildCommand}" />
                            <MenuItem Header="Тест" />
                        </ContextMenu>
                    </StackPanel.ContextMenu>
                    <TextBlock Text="{Binding Name}" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
        <i:Interaction.Behaviors>
            <service:BindableSelectedItemBehavior SelectedItem="{Binding Path=SelectedNode, Mode=TwoWay}"/>
        </i:Interaction.Behaviors>
    </TreeView>
</GroupBox>

<!-- Представление контейнера для форм --> <TabControl Grid.Column="1" Grid.Row="0" ItemsSource="{Binding Workspaces}"> <TabControl.Resources> <DataTemplate DataType="{x:Type vm:Workspace1ViewModel}"> <v:Workspace1/> </DataTemplate> <DataTemplate DataType="{x:Type vm:Workspace2ViewModel}"> <v:Workspace2/> </DataTemplate> </TabControl.Resources> <TabControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=HeaderText}"/> </DataTemplate> </TabControl.ItemTemplate> </TabControl>

В данный момент я могу удалять/создавать записи через контекстное меню.
Команды поведения узлов определены в ViewModel NodeViewModel

        #region AddChildCommand
    public ICommand AddChildCommand { get; }

    private bool CanAddChildCommandExecute(object param) =&gt; true;

    private void OnAddChildCommandExecuted(object param)
    {
        try {
            using (var context = new EFContext()) {
                var node = new CLASSNODE_DEFINITIONS {
                    type = Type,
                    parent_id = _Node.id
                };
                node.name = $&quot;new{node.type}1&quot;;
                node.disp = $&quot;New {node.type}&quot;;

                context.CLASSNODE_DEFINITIONS.Add(node);
                context.SaveChanges();

                Subnodes.Add(new NodeViewModel(node, this));
            }
        } catch (Exception e) {
            throw e;
        }

    }

    #endregion

Но теперь мне надо сделать следующее: допустим, при добавлении как то нужно

  1. передать узел, который был добавлен, в конструктор Workspace (формы т.е. View будут заготовлены для каждого типа объекта в каталоге), но свойство коллекции Workspaces находится НЕ на NodeViewModel, а на WinMainViewModel (как передать правильно не могу понять)
  2. выбрать его в дереве каталога
  3. как лучше всего реализавать изменение свойств объекта? в плане передачи данных и сввязываний

Как вы поняли это просто обычный древовидный каталог, где узлами могут быть разные типы данных и иметь разное поведение.

А при нажатиях ИЛИ по контекстному меню можно вызывать ещё какие то заготовленные View в Workspaces и манипулировать с объектом.

Вот ещё код:

Допустим форма для оборудования

    internal class Workspace1ViewModel : WorkspaceViewModelBase
    {
        public Workspace1ViewModel() => HeaderText = "1";
    public string EquipmentField = &quot;Equipment&quot;;
}

Это я делал разный тип ViewModel для разных функций в ContextMenu, пока всё работает

    internal class EquipmentNodeViewModel : NodeViewModel
    {
        public EquipmentNodeViewModel(CLASSNODE_DEFINITIONS node, NodeViewModel parent) : base(node, parent)
        {
    }
}

это для опор

    internal class Workspace2ViewModel : WorkspaceViewModelBase
    {
        public Workspace2ViewModel() => HeaderText = "2";
    public string EquipmentField = &quot;Support&quot;;
}

internal class WorkspaceViewModelBase : ViewModelBase
{
    public string HeaderText { get; set; }

    public override string ToString() =&gt; HeaderText;
}

aepot
  • 49,560
  • Я не понял вопроса, быть может недостаточно разобрался, но есть вот такой пример, возможно он содержит то что вам нужно. – aepot May 16 '21 at 11:05
  • @aepot Это у меня получилось реализовать, а теперь необходимо сделать формы свойств при клике на эти узлы и чтобы данные пользователь мог изменить – Undefined May 16 '21 at 11:16
  • @aerot эти формы определил как View (UserControls) со своими ViewModel и добавил в ресурсы TabControl А как дальше из узла (NodeViewModel, команда узлов определены тут) обратится к ViewModel главного окна (там свойство Workspaces) и добавить туда Workspace == форма я не понимаю

    Может я вообще запутался и то, что представил выше вообще не правильно Прошу помощи

    – Undefined May 16 '21 at 11:20
  • Ну например Style.Trigger, если IsFocused, то меняем ControlTemplate с TextBlock на TextBox, ну или сразу текстбоксами отображать. Если нужен конкретный пример, можете в родную разметку DataGrid заглянуть, там всё это реализовано. – aepot May 16 '21 at 11:23
  • @aepot Вот данный пример реализации (явно не правильной) может лучше даст понять что я бы хотел сделать ViewModelsService.WinMainViewModel.Workspaces.Add(new Workspace1ViewModel()); ViewModelsService.WinMainViewModel.SelectedNode = nodeVM;

    Сделал просто статический класс, и когда добавляю новый узел создаю новый Workspace и добавляю его в коллекцию для отображения (работает) А также изменяю SelectedNode (не работает)))

    – Undefined May 16 '21 at 11:34
  • Чтобы изменения свойств из кода влияли на интефейс, нужна реализация INotifyPropertyChnaged и привязка Binding к изменяющемуся свойству. – aepot May 16 '21 at 11:39

0 Answers0