UserControlCollection

View as Markdown

Definition

An observable collection of 3rd party framework elements, the purpose of which is to allow developers to add a custom control to the chart (e.g., add a button or create your own data grid). This framework collection resides on top of the ChartControl in order to prevent 3rd party custom controls from interfering with native NinjaTrader chart framework members. For example, if you wish to add a button to a chart, it is recommended to add it to this UserControlCollection rather than attempting to modify or add to any pre-existing NinjaTrader chart elements.

  1. This collection is provided “as-is” and does NOT contain any automatic layout options. By default, the last added framework element will reside on top of any previously added controls. This means it is possible for a user to install two NinjaScript objects which may be competing for an area of a chart.
  2. Once the NinjaScript object is removed from the chart by the user, the custom control will be automatically removed from the collection.
  1. This property should ONLY be accessed once your NinjaScript object has reached State.Historical or later
  2. You MUST use a Dispatcher in order to account for any UI threading errors. Please see the example below for proper usage
  3. It is imperative that you dispose of any custom control resources in State.Terminated to ensure there are no leaks between instances of the object

Property Value

ObservableCollection<System.Windows.FrameworkElement>

Syntax

UserControlCollection[int idx]

Examples

1private System.Windows.Controls.Button myBuyButton;
2private System.Windows.Controls.Button mySellButton;
3private System.Windows.Controls.Grid myGrid;
4
5// Define a custom event method to handle our custom task when the button is clicked
6private void OnMyButtonClick(object sender, RoutedEventArgs rea)
7{
8 System.Windows.Controls.Button button = sender as System.Windows.Controls.Button;
9 if (button != null)
10 Print(button.Name + " Clicked");
11}
12
13protected override void OnStateChange()
14{
15 if (State == State.SetDefaults)
16 {
17 Name = "SampleAddButton";
18 Description = "Adds a custom control to the chart";
19 IsOverlay = true;
20 }
21 else if (State == State.Configure)
22 {
23 }
24
25 // Once the NinjaScript object has reached State.Historical, our custom control can now be added to the chart
26 else if (State == State.Historical)
27 {
28 // Because we're dealing with UI elements, we need to use the Dispatcher which created the object
29 // otherwise we will run into threading errors...
30 // e.g, "Error on calling 'OnStateChange' method: You are accessing an object which resides on another thread."
31 // Furthermore, we will do this operation Asynchronously to avoid conflicts with internal NT operations
32 ChartControl.Dispatcher.InvokeAsync((() =>
33 {
34 // Grid already exists
35 if (UserControlCollection.Contains(myGrid))
36 return;
37
38 // Add a control grid which will host our custom buttons
39 myGrid = new System.Windows.Controls.Grid
40 {
41 Name = "MyCustomGrid",
42 // Align the control to the top right corner of the chart
43 HorizontalAlignment = HorizontalAlignment.Right,
44 VerticalAlignment = VerticalAlignment.Top,
45 };
46
47 // Define the two columns in the grid, one for each button
48 System.Windows.Controls.ColumnDefinition column1 = new System.Windows.Controls.ColumnDefinition();
49 System.Windows.Controls.ColumnDefinition column2 = new System.Windows.Controls.ColumnDefinition();
50
51 // Add the columns to the Grid
52 myGrid.ColumnDefinitions.Add(column1);
53 myGrid.ColumnDefinitions.Add(column2);
54
55 // Define the custom Buy Button control object
56 myBuyButton = new System.Windows.Controls.Button
57 {
58 Name = "MyBuyButton",
59 Content = "LONG",
60 Foreground = Brushes.White,
61 Background = Brushes.Green
62 };
63
64 // Define the custom Sell Button control object
65 mySellButton = new System.Windows.Controls.Button
66 {
67 Name = "MySellButton",
68 Content = "SHORT",
69 Foreground = Brushes.White,
70 Background = Brushes.Red
71 };
72
73 // Subscribe to each buttons click event to execute the logic we defined in OnMyButtonClick()
74 myBuyButton.Click += OnMyButtonClick;
75 mySellButton.Click += OnMyButtonClick;
76
77 // Define where the buttons should appear in the grid
78 System.Windows.Controls.Grid.SetColumn(myBuyButton, 0);
79 System.Windows.Controls.Grid.SetColumn(mySellButton, 1);
80
81 // Add the buttons as children to the custom grid
82 myGrid.Children.Add(myBuyButton);
83 myGrid.Children.Add(mySellButton);
84
85 // Finally, add the completed grid to the custom NinjaTrader UserControlCollection
86 UserControlCollection.Add(myGrid);
87
88 }));
89 }
90
91 // When NinjaScript object is removed, make sure to unsubscribe to button click events
92 else if (State == State.Terminated)
93 {
94 if (ChartControl == null)
95 return;
96
97 // Again, we need to use a Dispatcher to interact with the UI elements
98 ChartControl.Dispatcher.InvokeAsync((() =>
99 {
100 if (myGrid != null)
101 {
102 if (myBuyButton != null)
103 {
104 myGrid.Children.Remove(myBuyButton);
105 myBuyButton.Click -= OnMyButtonClick;
106 myBuyButton = null;
107 }
108 if (mySellButton != null)
109 {
110 myGrid.Children.Remove(mySellButton);
111 mySellButton.Click -= OnMyButtonClick;
112 mySellButton = null;
113 }
114 }
115 }));
116 }
117}

AddOnFrameWorkExample2