I've been following the documentation here: https://ninjatrader.com/support/help...development_ov erview.htm
I'm at a point where I get this error when I click on my menu item in the "New" section: (see attached).
This is the AddOn:
#region Using declarations using System; using NinjaTrader.Gui.Tools; using System.Windows; using NinjaTrader.Gui; using System.Windows.Controls; using System.Xml.Linq; using System.Windows.Media; #endregion //This namespace holds Add ons in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.AddOns { public class MyCustomAddOn : AddOnBase { // menu stuff private NTMenuItem MenuItem; private NTMenuItem ControlCenterNewMenu; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Add on here."; Name = "CustomeAddOn"; } else if (State == State.Configure) { } else if (State == State.DataLoaded) { } else if (State == State.Terminated) { } } protected override void OnWindowCreated(Window window) { // We want to place the menu item for the AddOn in the Control Center's "New" menu // First obtain a reference to the Control Center window ControlCenter cc = window as ControlCenter; if (cc == null) return; /* Determine we want to place the AddOn in the Control Center's "New" menu Other menus can be accessed via the control's "Automation ID". For example: toolsMenuItem, workspacesMenuItem, connectionsMenuItem, helpMenuItem. */ ControlCenterNewMenu = cc.FindFirst("ControlCenterMenuItemNew") as NTMenuItem; if (ControlCenterNewMenu == null) return; // 'Header' sets the name of our AddOn seen in the menu structure MenuItem = new NTMenuItem { Header = "Custom Addon", Style = Application.Current.TryFindResource("MainMenuItem") as Style }; // Add our AddOn into the "New" menu ControlCenterNewMenu.Items.Add(MenuItem); MenuItem.Click += OnMenuItemClick; } private void OnMenuItemClick(object sender, EventArgs e) { Core.Globals.RandomDispatcher.BeginInvoke(new Action(() => new ExporterWindow().Show())); } // Class for Window management // create a NT8 window with the name StableMetricsWindow // this window will be used to display the prometheus URL public class ExporterWindow : NTWindow { public ExporterWindow() { Caption = "Custom Addon Window"; Width = 800; Height = 600; TabControl tc = new TabControl(); // Attached properties defined in TabControlManager class should be set to achieve tab moving, adding/removing tabs //TabControlManager.SetIsMovable(tc, true); //TabControlManager.SetCanAddTabs(tc, true); //TabControlManager.SetCanRemoveTabs(tc, true); // if ability to add new tabs is desired, TabControl has to have attached property "Factory" set. TabControlManager.SetFactory(tc, new AddOnFrameworkWindowFactory()); Content = tc; /* In order to have link buttons functionality, tab control items must be derived from Tools.NTTabPage They can be added using extension method AddNTTabPage(NTTabPage page) */ tc.AddNTTabPage(new AddOnFrameworkTab()); } } /* Class which implements Tools.INTTabFactory must be created and set as an attached property for TabControl in order to use tab page add/remove/move/duplicate functionality */ public class AddOnFrameworkWindowFactory : INTTabFactory { // INTTabFactory member. Required to create parent window public NTWindow CreateParentWindow() { return new ExporterWindow(); } // INTTabFactory member. Required to create tabs public NTTabPage CreateTabPage(string typeName, bool isTrue) { return new AddOnPage(); } } public class AddOnFrameworkTab : NTTabPage { public AddOnFrameworkTab() { AddOnFrameworkWindowFactory myAddOnFrameworkWindowFactory = new AddOnFrameworkWindowFactory(); Content = myAddOnFrameworkWindowFactory.CreateTabPage("AddOnPage", true); } // implement a basic save protected override void Save(XElement element) { // Save the tab page if (element == null) return; } // implement a basic restore protected override void Restore(XElement element) { // Restore the tab page if (element == null) return; } // implement a basic GetHeaderPart protected override string GetHeaderPart(string header) { return "AddOnTab"; } } public class AddOnPage : NTTabPage { public AddOnPage() { // create the parent window Grid grid = new Grid(); grid.Background = new SolidColorBrush(Colors.Transparent); ColumnDefinition col1 = new ColumnDefinition(); // bug in the NT documentation, missing a space here col1.Width = new GridLength(55); ColumnDefinition col2 = new ColumnDefinition(); // bug in the NT documentation, missing a space here col2.Width = new GridLength(45); grid.ColumnDefinitions.Add(col1); grid.ColumnDefinitions.Add(col2); // Create a textblock to display the prometheus URL TextBlock textBlock = new TextBlock(); textBlock.Text = "Some Text: "; } // implement a basic save protected override void Save(XElement element) { // Save the tab page if (element == null) return; } // implement a basic restore protected override void Restore(XElement element) { // Restore the tab page if (element == null) return; } // implement a basic GetHeaderPart protected override string GetHeaderPart(string header) { return "AddOnTab"; } } // Will be called as a new NTWindow is destroyed. It will be called in the thread of that window protected override void OnWindowDestroyed(Window window) { if (MenuItem != null && window is ControlCenter) { if (ControlCenterNewMenu != null && ControlCenterNewMenu.Items.Contains(MenuItem)) ControlCenterNewMenu.Items.Remove(MenuItem); MenuItem.Click -= OnMenuItemClick; MenuItem = null; } } } }
I'm not using a XAML file. I'm opting to do everting in code. I don't care about persistence in the workspace, so took that out as well. The tab would be simple, so took out the create, move, delete options from TabControl.
Google searched point to XML errors and such. I'm VERY much not a UI / FrontEnd sort of person, so all lot of this is a bit new and overwhelming.
Cheers!
Comment