NinjaTrader 8中如何在指标中捕获上下箭头键事件?
NinjaTrader 8中自定义指标捕获上下箭头键的实现方案
问题背景
- 开发环境:C#、WPF(非WinForm)、NinjaTrader 8
- 核心问题:NinjaTrader默认将上下箭头键绑定为图表移动操作,自定义指标中通过
PreviewKeyDown无法捕获这两个按键,推测事件已被父图表控件截获 - 需求:在自定义指标中接管上下箭头键的事件逻辑,官方大概率不支持该需求,需通过非官方方式实现
可行实现方案
一、基于NinjaTrader AddOn架构重写全局按键处理
NinjaTrader的AddOn可全局介入应用事件流程,通过它可以拦截图表控件的按键事件:
- 创建继承自
NinjaTrader.Gui.Tools.AddOnBase的AddOn类 - 在窗口创建/销毁时绑定/解绑图表控件的
PreviewKeyDown事件 - 在事件处理中识别上下箭头键,控制事件是否继续传递
示例代码:
public class ArrowKeyInterceptorAddOn : AddOnBase { protected override void OnWindowCreated(Window window) { base.OnWindowCreated(window); // 定位图表核心控件,需根据NT8实际控件结构调整 var chartControl = window.FindName("ChartControl") as NinjaTrader.Gui.Chart.ChartControl; if (chartControl != null) { chartControl.PreviewKeyDown += ChartControl_PreviewKeyDown; } } private void ChartControl_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key is Key.Up or Key.Down) { // 此处可先执行自定义指标的按键逻辑 // 若要让事件传递到子控件(你的自定义指标),设置e.Handled = false // 若要完全接管按键,阻止NT8默认的图表移动,设置e.Handled = true e.Handled = false; } } protected override void OnWindowDestroyed(Window window) { var chartControl = window.FindName("ChartControl") as NinjaTrader.Gui.Chart.ChartControl; if (chartControl != null) { chartControl.PreviewKeyDown -= ChartControl_PreviewKeyDown; } base.OnWindowDestroyed(window); } }
注意:需通过WPF Inspector或Spy++确认NT8图表控件的准确名称/类型,避免因版本更新导致控件结构变化。
二、通过可视化树重写父控件事件路由
如果AddOn方式过于全局,可针对单个自定义指标的父控件进行事件拦截:
- 在指标初始化阶段,通过可视化树查找父图表控件
- 绑定父控件的
PreviewKeyDown事件,优先处理上下箭头键
示例代码:
// 在指标的OnStateChange方法(State.Setup阶段)调用此方法 private void HookParentChartKeyEvents() { // MyIndicatorControl为自定义指标的UI控件实例 var parentChart = FindVisualParent<NinjaTrader.Gui.Chart.ChartControl>(MyIndicatorControl); if (parentChart != null) { parentChart.PreviewKeyDown += ParentChart_PreviewKeyDown; } } private void ParentChart_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key is Key.Up or Key.Down) { // 执行自定义指标的按键逻辑 HandleArrowKeyInput(e.Key); // 按需控制事件是否继续传递 e.Handled = true; } } // 可视化树父控件查找辅助方法 private T FindVisualParent<T>(DependencyObject child) where T : DependencyObject { var parent = VisualTreeHelper.GetParent(child); if (parent == null) return null; return parent as T ?? FindVisualParent<T>(parent); }
注意事项
- NT8内部控件结构可能随版本更新变化,代码需适配对应版本
- 此类修改属于非官方自定义,后续版本更新可能导致功能失效
- 测试时需排查与其他AddOn或系统默认功能的按键冲突
内容的提问来源于stack exchange,提问作者llqh
相关产品推荐
相关产品推荐

