Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

XAML from external file, inner node question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    XAML from external file, inner node question

    Hello all.

    Attached is an indicator which adds usercontrols (Grids and Buttons) to the chart, by parsing XAML from and external file (included). The indicator is just a modification of the built-in SMA.

    To the left of the chart is a grid containing a Button at its root level, and another inner Grid which also contains a Button of its own. Both buttons work: they double the Period property, and then simulate the pressing of F5 to refresh the chart (via SendKeys).

    In the middle of the chart, however, is a control created from that same XAML file, but it extracts just the inner grid and its inner button. Although the button press is detected (it prints to Output window and does change the Period), it doesn't seem to refresh the chart. The only reason I can think of is that it is interfering with SendKeys F5.

    Can someone please shed some light?


    Code:
    //
    // Copyright (C) 2018, NinjaTrader LLC <www.ninjatrader.com>.
    // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
    //
    #region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion
    using System.Windows.Markup;
    using System.IO;
    using System.Windows.Controls;
    
    // This namespace holds indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {
    	/// <summary>
    	/// The SMAwithButtons (Simple Moving Average) is an indicator that shows the average value of a security's price over a period of time.
    	/// </summary>
    	public class SMAwithButtons : Indicator
    	{
    		private double priorSum;
    		private double sum;
    
    		protected override void OnStateChange()
    		{
    			if (State == State.SetDefaults)
    			{
    				Description					= NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionSMA;
    				Name						= "SMAwithButtons";
    				IsOverlay					= true;
    				IsSuspendedWhileInactive	= true;
    				Period						= 14;
    
    				AddPlot(Brushes.Goldenrod, NinjaTrader.Custom.Resource.NinjaScriptIndicatorNameSMA);
    			}
    			else if (State == State.Configure)
    			{
    				priorSum	= 0;
    				sum			= 0;
    			}
                else if (State == State.Historical)
                {
                    if (ChartControl != null )
                    {
                        ChartControl.Dispatcher.InvokeAsync((Action)(() =>
                        {
                           Insert_GridInGrid();
                           Insert_InnerGridOnly();
                        }));
                    }
                }
                else if (State == State.Terminated)
                {
                }
            }
    
            private void DisconnectMyControls()
            {
                throw new NotImplementedException();
            }
    
    
            private void Insert_GridInGrid()
            {
                FileStream fs = new FileStream(System.IO.Path.Combine(NinjaTrader.Core.Globals.UserDataDir, "bin", "Custom", "Indicators", "SMAwithButtons.xaml"), FileMode.Open);
    
                Grid rootGrid = (Grid)XamlReader.Load(fs);
    
                Button buttonFromFile = LogicalTreeHelper.FindLogicalNode(rootGrid, "OuterButton") as Button;
                buttonFromFile.Click += ClickDetector;            
    
                buttonFromFile = LogicalTreeHelper.FindLogicalNode(rootGrid, "InnerButton") as Button;
                buttonFromFile.Click += ClickDetector;            
    
                UserControlCollection.Add(rootGrid);
            }
    
            private void Insert_InnerGridOnly()
            {
                FileStream fs = new FileStream(System.IO.Path.Combine(NinjaTrader.Core.Globals.UserDataDir, "bin", "Custom", "Indicators", "SMAwithButtons.xaml"), FileMode.Open);
    
                Grid rootGrid = (Grid)XamlReader.Load(fs);
    
                Grid innerGrid = LogicalTreeHelper.FindLogicalNode(rootGrid, "InnerGrid") as Grid;
                Button innerButton;
    
                //innerButton = LogicalTreeHelper.FindLogicalNode(rootGrid, "InnerButton") as Button;
                innerButton = LogicalTreeHelper.FindLogicalNode(innerGrid, "InnerButton") as Button;
                innerButton.Click += ClickDetector;
    
                UserControlCollection.Add(innerGrid); //add only innerGrid to usercontrols
            }
    
            private void ClickDetector(object sender, RoutedEventArgs e)
            {
                Print("Button received:" + (sender as Button).Content);
                if (Period > 200) Period = 10;
                else Period = Period * 2;
                System.Windows.Forms.SendKeys.SendWait("{F5}");
            }
    
    		protected override void OnBarUpdate()
    		{
    			if (BarsArray[0].BarsType.IsRemoveLastBarSupported)
    			{
    				if (CurrentBar == 0)
    					Value[0] = Input[0];
    				else
    				{
    					double last = Value[1] * Math.Min(CurrentBar, Period);
    
    					if (CurrentBar >= Period)
    						Value[0] = (last + Input[0] - Input[Period]) / Math.Min(CurrentBar, Period);
    					else
    						Value[0] = ((last + Input[0]) / (Math.Min(CurrentBar, Period) + 1));
    				}
    			}
    			else
    			{
    				if (IsFirstTickOfBar)
    					priorSum = sum;
    
    				sum = priorSum + Input[0] - (CurrentBar >= Period ? Input[Period] : 0);
    				Value[0] = sum / (CurrentBar < Period ? CurrentBar + 1 : Period);
    			}
    		}
    
    		#region Properties
    		[Range(1, int.MaxValue), NinjaScriptProperty]
    		[Display(ResourceType = typeof(Custom.Resource), Name = "Period", GroupName = "NinjaScriptParameters", Order = 0)]
    		public int Period
    		{ get; set; }
    		#endregion
    	}
    }
    Attached Files

    #2
    Hello zambi,

    While this is outside of what is supported by NinjaTrader Support, as a tip the issue is likely with SendKey.

    Try using Keyboard.FocusedElement.RaiseEvent(). The RolloverIndications indicator demonstrates.


    Another community member of the forum as able to send keys in this way.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Thanks Chelsea.

      While your suggestion of changing keyboard focus did work, I no longer think it's a SendKeys issue, but rather how I'm parsing and applying Xaml to my chart. I realize both are outside the mandate of NT's support team, so I’m not expecting any further investigation on your part.

      I’m only posting this revised version of the indicator in case someone wants to refer to it. (I'll probably want to revisit it myself). I've added to the indicator multiple approaches for dealing with Xaml, including a workaround from MSDN that suggests mixing XamlReader and XmlReader.

      Thanks again.
      Attached Files

      Comment


        #4
        Hello zambi,

        The button itself is being loaded from the xaml page, is this correct?

        And the button is actually appearing on the chart?

        And when clicking the button you get the print in the output window?

        (This would make me think the issue is not with loading the xaml)

        Below is a link to an example addon that loads from an external xaml page.
        Chelsea B.NinjaTrader Customer Service

        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by Barry Milan, Today, 10:35 PM
        1 response
        6 views
        0 likes
        Last Post NinjaTrader_Manfred  
        Started by WeyldFalcon, 12-10-2020, 06:48 PM
        14 responses
        1,427 views
        0 likes
        Last Post Handclap0241  
        Started by DJ888, Yesterday, 06:09 PM
        2 responses
        9 views
        0 likes
        Last Post DJ888
        by DJ888
         
        Started by jeronymite, 04-12-2024, 04:26 PM
        3 responses
        40 views
        0 likes
        Last Post jeronymite  
        Started by bill2023, Today, 08:51 AM
        2 responses
        16 views
        0 likes
        Last Post bill2023  
        Working...
        X