OnRenderTargetChanged()

View as Markdown

Definition

Called whenever a Chart’s RenderTarget is created or destroyed. OnRenderTargetChanged() is used for creating / cleaning up resources such as a SharpDX.Direct2D1.Brush used throughout your NinjaScript class.

  • A RenderTarget will be created and destroyed several times during the lifetime of a chart. For example, a user resizing the chart would cause the RenderTarget to be re-created as the chart is rendered to reflect the new dimensions. Another example is when a user clicks on the chart as a RenderTarget is used during hit testing. Since there are multiple RenderTargets, you MUST ensure the resource being used belongs to the destination target. In practice, all you need to understand is if you are using a device resource (e.g., custom SharpDX Brush) throughout different event methods, you should recreate these resource during OnRenderTargetChanged() which ensures the device resource is updated correctly as the devices context changes.
  • During initialization your NinjaScript indicators and strategies are guaranteed to see State.Configure before OnRenderTargetChanged() would be called.

Method Return Value

This method does not return a value.

Syntax

You may override the method in your indicator with the following syntax:

public override void OnRenderTargetChanged() \{ \}

  • Each DirectX render target requires its own brushes. You must create a brushes directly in OnRender() or using OnRenderTargetChanged(). If you do not you will receive an error at run time similar to: “A direct X error has occurred while rendering the chart: HRESULT: [0x88990015], Module: [SharpDX.Direct2D1], ApiCode: [D2DERR_WRONG_RESOURCE_DOMAIN/WrongResourceDomain], Message: The resource was realized on the wrong render target. : Each DirectX render target requires its own brushes. You must create brushes directly in OnRender() or using OnRenderTargetChanged(). Please see the example below on using OnRenderTargetChanged() with brush that needs to be recalculated, or OnRender() for an example of recreating a static brush.

Parameters

This method does not accept any parameters.

  • If you are exclusively using resources in OnRender() (e.g., not passing values from OnStateChange() or other events) you only need to create and dispose of the resource in OnRender(). The OnRenderTargetChanged() concepts illustrated below would not need to be applied.
  • For a walk through for using the SharpDX RenderTarget, please see the educational resource Using SharpDX for Custom Chart Rendering.

Examples

Recalculating a SharpDX Brush conditionally in OnBarUpdate()

1private SharpDX.Direct2D1.Brush dxBrush = null; // the SharpDX brush used for rendering
2private System.Windows.Media.SolidColorBrush brushColor; // used to determine the color of the brush conditionally
3
4protected override void OnStateChange()
5{
6 if (State == State.SetDefaults)
7 {
8 Name = "OnRenderTargetChanged Example";
9 IsOverlay = false;
10 }
11}
12
13protected override void OnBarUpdate()
14{
15 if (Close[0] > Open[0])
16 {
17 brushColor = Brushes.Green;
18 }
19 else if (Close[0] < Open[0])
20 {
21 brushColor = Brushes.Red;
22 }
23 else brushColor = Brushes.Blue;
24}
25
26public override void OnRenderTargetChanged()
27{
28 // if dxBrush exists on first render target change, dispose of it
29 if (dxBrush != null)
30 {
31 dxBrush.Dispose();
32 }
33
34 // recalculate dxBrush from value calculated in OnBarUpdated when RenderTarget is recreated
35 if (RenderTarget != null)
36 dxBrush = brushColor.ToDxBrush(RenderTarget);
37}
38
39protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
40{
41 // fill a custom SharpDX rectangle using the dx brush
42 RenderTarget.FillRectangle(new SharpDX.RectangleF(ChartPanel.X, ChartPanel.Y, ChartPanel.W, ChartPanel.H), dxBrush);
43}

Recalculating a SharpDX Brush based on user input

1private SharpDX.Direct2D1.Brush dxBrush = null; // the SharpDX brush used for rendering
2
3protected override void OnStateChange()
4{
5 if (State == State.SetDefaults)
6 {
7 Name = "OnRenderTargetChanged Example";
8 IsOverlay = false;
9 UserBrush = Brushes.Red; // user selection pushed to the UI
10 }
11}
12
13public override void OnRenderTargetChanged()
14{
15 // if dxBrush exists on first render target change, dispose of it
16 if (dxBrush != null)
17 {
18 dxBrush.Dispose();
19 }
20
21 // recalculate dxBrush from user defined brush when RenderTarget is recreated
22 if (RenderTarget != null)
23 dxBrush = UserBrush.ToDxBrush(RenderTarget);
24}
25
26protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
27{
28 // fill a custom SharpDX rectangle using the dx brush
29 RenderTarget.FillRectangle(new SharpDX.RectangleF(ChartPanel.X, ChartPanel.Y, ChartPanel.W, ChartPanel.H), dxBrush);
30}
31
32[XmlIgnore]
33public Brush UserBrush { get; set; } // brush selection set by user in UI
34
35[Browsable(false)]
36public string MyBrushSerialize // string used to serialize selection set by user in UI
37{
38 get { return Serialize.BrushToString(UserBrush); }
39 set { UserBrush = Serialize.StringToBrush(value); }
40}