I have written my first indicator and I have a widget that exposes 2 text boxes, when i type in the text box ninjatrader opens the instrument picker and all my typed characters go there, so I am not directly able to type in my text box but i can copy text to it, so I am still able to use my indicator.
But it will be nice to just be able to type into my textboxes and not having to write my text on notepad and then copy it to my text box. I have tried multiple solutions co-pilot gave me but he has also sort of given up, and both me and co-pilot have sort of accepted this reality.
But if anyone has a fix for this it will be really awesome, below i my complete widget -
private void AddFilterWidget()
{
// Ensure we run on UI thread
if (ChartControl == null)
return;
ChartControl.Dispatcher.Invoke(() =>
{
try
{
RemoveFilterWidget(); // ensure no duplicate
widgetContainer = new Grid
{
Width = 1000,
Height = 100,
Background = new SolidColorBrush(Color.FromArgb(10, 10, 10, 10)),
Margin = new Thickness(6),
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Top
};
widgetContainer.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(300) }); // textbox
widgetContainer.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(200) }); // checkboxes
widgetContainer.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(300) }); // checkboxes
widgetContainer.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(200) }); // draw button
var txtPanel = new StackPanel { Orientation = Orientation.Vertical, Margin = new Thickness(4) };
// Setup Ids
var setupPanel = new Grid { Margin = new Thickness(2) };
setupPanel.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // Label
setupPanel.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); // TextBox
var lblSetupIds = new Label { Content = “Setup Ids”, Margin = new Thickness(2, 0, 2, 0), Foreground = Brushes.White };
Grid.SetColumn(lblSetupIds, 0);
txtSetupIds = new TextBox
{
Text = setupIds,
Margin = new Thickness(2),
VerticalContentAlignment = VerticalAlignment.Center
};
// attach safeguard
txtSetupIds.GotFocus += (s, e) =>
{
// Clear chart-level instrument entry mode
Keyboard.ClearFocus();
// Immediately refocus the textbox
txtSetupIds.Focus();
};
Grid.SetColumn(txtSetupIds, 1);
setupPanel.Children.Add(lblSetupIds);
setupPanel.Children.Add(txtSetupIds);
// DB Filename
var dbPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(2) };
var lblDBFileName = new Label { Content = “DB Filename”, Margin = new Thickness(2, 4, 2, 0), Foreground = Brushes.White };
txtDBFileName = new TextBox
{
Text = dBFileName,
Margin = new Thickness(2),
VerticalContentAlignment = VerticalAlignment.Center
};
txtDBFileName.GotFocus += (s, e) =>
{
Keyboard.ClearFocus();
txtDBFileName.Focus();
};
dbPanel.Children.Add(lblDBFileName);
dbPanel.Children.Add(txtDBFileName);
// Add both panels into the column
txtPanel.Children.Add(setupPanel);
txtPanel.Children.Add(dbPanel);
Grid.SetColumn(txtPanel, 0);
var chkPanel = new StackPanel { Orientation = Orientation.Vertical, Margin = new Thickness(4) };
chkShowLong = new CheckBox { Content = “Show long trades?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkShowShort = new CheckBox { Content = “Show short trades?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkIsTraded = new CheckBox { Content = “Show traded trades?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkNotTraded = new CheckBox { Content = “Show not-traded trades?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkPanel.Children.Add(chkShowLong);
chkPanel.Children.Add(chkShowShort);
chkPanel.Children.Add(chkIsTraded);
chkPanel.Children.Add(chkNotTraded);
Grid.SetColumn(chkPanel, 1);
var chkPanel1 = new StackPanel { Orientation = Orientation.Vertical, Margin = new Thickness(4) };
chkShowTradedDesc = new CheckBox { Content = “Show traded trade descriptions?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkShowUnTradedDesc = new CheckBox { Content = “Show not-traded trade descriptions?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkShowTradeEntries = new CheckBox { Content = “Show entry signal names?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkShowTradeExits = new CheckBox { Content = “Show exit signal names?”, IsChecked = false, Margin = new Thickness(0, 0, 0, 2) };
chkPanel1.Children.Add(chkShowTradedDesc);
chkPanel1.Children.Add(chkShowUnTradedDesc);
chkPanel1.Children.Add(chkShowTradeEntries);
chkPanel1.Children.Add(chkShowTradeExits);
Grid.SetColumn(chkPanel1, 2);
btnApply = new Button { Content = “(Re) Draw”, Width = 70, Height = 30, Margin = new Thickness(4), HorizontalAlignment = HorizontalAlignment.Left };
Grid.SetColumn(btnApply, 3);
widgetContainer.Children.Add(txtPanel);
widgetContainer.Children.Add(chkPanel);
widgetContainer.Children.Add(chkPanel1);
widgetContainer.Children.Add(btnApply);
// Place widget on chart - ChartControl is a Canvas-like control; add to its parent overlay
// Use ChartControl.Parent as a container for overlaying controls
var parent = ChartControl.Parent as Grid;
if (parent != null)
{
parent.Children.Add(widgetContainer);
}
else
{
// fallback: add to ChartControl itself if possible
try { ChartControl.Children.Add(widgetContainer); } catch { }
}
btnApply.Click += BtnApply_Click;
var chartWindow = Window.GetWindow(ChartControl);
if (chartWindow != null)
{
chartWindow.PreviewKeyDown -= ChartControl_PreviewKeyDown; // avoid duplicate
chartWindow.PreviewKeyDown += ChartControl_PreviewKeyDown;
Print(“[INFO] TradeViewer widget key handler attached”);
}
}
catch (Exception ex)
{
Print("[ERROR] Widget error: " + ex.Message);
}
});
}