SharpDX技术咨询:如何获取RenderTarget上已绘制对象列表?
关于SharpDX + NinjaTrader 8获取已绘制对象列表的解决方案
首先明确:SharpDX的RenderTarget本身不会存储已绘制对象的列表。它属于即时模式渲染API,所有绘制操作都是直接输出到显存目标表面,执行后不会保留任何绘制对象的状态或引用,因此无法直接从RenderTarget中读取已绘制的对象。
针对NinjaTrader 8的场景,有两种可行的处理方式:
1. 自行维护自定义绘制对象列表
如果是你自己通过SharpDX API手动绘制的对象,需要在代码中主动维护一个集合来记录这些对象:
- 定义一个包含绘制属性的类(比如形状、位置、颜色、类型等)
- 创建
List<T>或其他集合存储这些对象 - 在
OnRender方法中遍历集合完成绘制,同时可以随时添加/移除对象实现动态管理 - 遍历已绘制对象时直接操作这个集合即可
示例代码框架:
// 自定义绘制对象类 public class CustomDrawItem { public enum DrawShape { Line, Rectangle, Text } public DrawShape Shape { get; set; } public RectangleF Bounds { get; set; } public Color DrawColor { get; set; } // 可根据需求添加更多属性(比如文本内容、线条宽度等) } // 在你的指标/策略类中 private List<CustomDrawItem> _myDrawItems = new List<CustomDrawItem>(); protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { base.OnRender(chartControl, chartScale); var renderTarget = chartControl.Properties.RenderTarget; // 遍历自定义列表,绘制所有对象 foreach (var item in _myDrawItems) { var brush = new SharpDX.Direct2D1.SolidColorBrush(renderTarget, item.DrawColor); switch(item.Shape) { case CustomDrawItem.DrawShape.Rectangle: renderTarget.DrawRectangle(brush, item.Bounds); break; case CustomDrawItem.DrawShape.Line: renderTarget.DrawLine(brush, new Vector2(item.Bounds.Left, item.Bounds.Top), new Vector2(item.Bounds.Right, item.Bounds.Bottom)); break; // 其他形状的绘制逻辑 } brush.Dispose(); // 注意释放SharpDX资源,避免内存泄漏 } // 示例:条件触发添加新绘制对象 if (SomeConditionIsMet()) { _myDrawItems.Add(new CustomDrawItem { Shape = CustomDrawItem.DrawShape.Rectangle, Bounds = new RectangleF(50, 50, 100, 80), DrawColor = Color.DodgerBlue }); } }
2. 访问NinjaTrader内置绘制对象集合
如果使用的是NinjaTrader自带的DrawLine、DrawRectangle等方法绘制的对象,这些对象由NinjaTrader框架托管,可以通过ChartControl.DrawObjects获取内置绘制对象的集合,直接遍历这个集合就能访问所有系统托管的已绘制元素:
protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { base.OnRender(chartControl, chartScale); // 遍历NinjaTrader内置的绘制对象 foreach (var drawObj in chartControl.DrawObjects) { // 根据对象类型处理,比如判断是否是LineDrawObject、RectangleDrawObject等 if (drawObj is LineDrawObject lineObj) { // 访问线条的属性:lineObj.StartX, lineObj.StartY, lineObj.Color等 } else if (drawObj is RectangleDrawObject rectObj) { // 访问矩形的属性:rectObj.Left, rectObj.Top, rectObj.Width等 } } }
注意事项
- 自行维护列表时,要注意SharpDX资源的释放(比如笔刷、画笔),避免内存泄漏
- 如果涉及多线程操作绘制对象列表,需要加锁保证线程安全
- NinjaTrader内置的
DrawObjects集合仅包含通过NinjaTrader官方绘制方法创建的对象,不包含你直接用SharpDX API绘制的自定义对象
内容的提问来源于stack exchange,提问作者Faran Rashid
相关产品推荐
相关产品推荐

