/// <summary> /// Iterate through all DLLs in same location as the editor and load all non-abstract classes derived from NodeViewModel. /// </summary> public static void LoadNodeViewModels() { NodeViewModelsImpl.Clear(); NodeViewModelLookup.Clear(); // Go through each custom loaded type foreach (Type type in ExtensibilityUtils.Types) { if (!type.IsAbstract && type.IsSubclassOf(typeof(NodeViewModel))) { NodeViewModelsImpl.Add(type); } } foreach (Type viewModel in NodeViewModelsImpl) { NodeViewModelAttribute viewModelAttribute = viewModel.GetCustomAttribute <NodeViewModelAttribute>(); if (!NodeViewModelLookup.ContainsKey(viewModelAttribute.NodeType)) { NodeViewModelLookup.Add(viewModelAttribute.NodeType, (SpeechNode node) => { return(Activator.CreateInstance(viewModel, node) as NodeViewModel); }); } else { CelDebug.Fail("Duplicate view model type for node type " + viewModelAttribute.NodeType.Name); continue; } } }
public StoryEditor() : base(new StoryEditorViewModel()) { InitializeComponent(); ContextMenu contextMenu = new ContextMenu(); MenuItem createMenuItem = new MenuItem() { Header = "Create" }; contextMenu.Items.Add(createMenuItem); foreach (Type type in NodeViewModelFactory.NodeViewModels) { NodeViewModelAttribute nodeAttribute = type.GetCustomAttribute <NodeViewModelAttribute>(); MenuItem nodeMenuItem = new MenuItem() { Header = nodeAttribute.MenuName }; nodeMenuItem.DataContext = nodeAttribute.NodeType; nodeMenuItem.Click += NodeMenuItem_Click; createMenuItem.Items.Add(nodeMenuItem); } // Network swallows the context menu and right button down events // so we have to manually open the context menu in the preview event Network.ContextMenu = contextMenu; Network.PreviewMouseRightButtonDown += (sender, e) => { Network.ContextMenu.DataContext = e.GetPosition(Network); Network.ContextMenu.IsOpen = true; }; }