Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Cannot reflect expandable object?

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

    Cannot reflect expandable object?

    This test indicator has an expandable object as a property. The indicator compiles fine, and the expandable property displays just fine in the Indicators dialog. However, when I go to save the workspace, the log shows an error saying it could not save the indicator. The log message is:
    Could not save indicator 'AAExpandableProperty:' There was an error reflecting type 'NinjaTrader.NinjaScript.Indicators.AAExpandablePr operty'.
    The expandable property does not have a serializer (does it need one?), but the log error message does not sound as if that is the problem. The test indicator code is:
    Code:
    #region Using declarations
    using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    using Vsa;
    #endregion
    
    //This namespace holds Indicators in this folder and is required. Do not change it. 
    namespace NinjaTrader.NinjaScript.Indicators
    {
        public class AAExpandableProperty : VsaIndicatorBase
        {
            public AAExpandableProperty() : base(DbgType.None) {}
            
            protected override void OnStateChange()
            {
                switch (State)
                {
                    case State.SetDefaults:
                        // The property cannot do this initialization for itself, because a field initializer cannot access "this"
                         barNumbers = new BarNumbering(this);
                        break;
                }
            }
            
            // BarNumbering property
            //    * "barNumbers" is initialized by the main progam, because "this" must be passed to its constructor
            private BarNumbering barNumbers;
            [Browsable(true)]
            [Display(Order = 0, Name = "Bar Numbering", Description = "Tooltips are not shown for BarNumbering")]
            public BarNumbering BarNumbers
            {
                get{return barNumbers;}
                set{barNumbers = value;}
            }
        
            // //////////////////////////////////////////////////////////////////////////////////////////////////////
            // Type converter needed to display BarNumbering in a property grid; converts BarNumbering <--> string
            public class BarNumberingTypeConverter : ExpandableObjectConverter
            {
                // Convert from a string to a BarNumbering; returning true means the string in the Indicators grid will be editable
                public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
                    { return false; }                                // Make the string non-editable
    
                // Convert to a string from a ; this is what will be displayed in the Indicators dialog
                public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
                    { return false; }
             
                public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
                                                    object value, Type destinationType)
                {
                    return (destinationType == typeof(String) && value is BarNumbering)
                        ? ((BarNumbering)value).ToString()
                        : base.ConvertTo(context, culture, value, destinationType);
                }
            }
    
    
            // //////////////////////////////////////////////////////////////////////////////////////////////////////
            // The bar numbering class
            [TypeConverter(typeof(BarNumberingTypeConverter))]
            [Description("Expand to set the bar numbering options")]
            public class BarNumbering
            {
                // ////////////////////////////////////////////////////////////////////////////////////////
                // Constructors -- always need a parent, because the debug stuff needs an instance
                private VsaIndicatorBase parent;                // Needed to access the debug printing
                public BarNumbering(VsaIndicatorBase parent)
                {
                    this.parent = parent;
                }
    
                // ///////////////////////////////  Enable  ///////////////////////////////
                private bool enable = false;
                [DefaultValue(typeof(bool), "false")]
                [TypeConverter(typeof(EnableDisableConverter))]
                [Browsable(true)]
                [Display(Order = 10, Name = "Enable bar numbering",
                               Description = "Enables/disables displaying bar numbers near the bars")]
                public bool Enable
                {
                    get { parent.PrintGetEntry("returning " + enable.ToString());
                          return enable; }
                    set { parent.PrintSetEntry("old value=" + enable.ToString() + "  new value=" + value.ToString());
                          enable = value; }
                }
            }    // class BarNumbering
        }    // classs AAExpandableProperty
    }
    Am I missing something in the code and that is preventing reflection, or is this an NT bug of some sort?
    Last edited by ETFVoyageur; 08-04-2016, 09:08 AM.

    #2
    Hello,

    Thank you for the post.

    I was going to test this but see the object inherits from something I do not have.

    Based on the error, it seems that serialization may play a role, or that some object is trying to be saved that can not be saved. It would be hard to say without narrowing down to what specifically is causing the error.

    If you would like to provide a complete example, I could review that or if you want you could also try to create a new indicator in the same way as this but comment out all the properties and just make the expandable object. Can the indicator serialize? This will tell you if one of the properties or the expandable object its self can not save.

    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      Jesse,

      Thanks for taking a look. I should have mentioned that commenting out the indicator's only property, BarNumbers, makes the problem go away. The problem shows up only when the indicator has the expandable property included.

      I have just emailed an Export version to you, subject beginning ATTN: Jesse. You should have it by now.

      As noted in the email, the version I sent you does have the property commented out (lines 30-36) and does not exhibit the issue. Restoring the property by uncommenting those lines will match what I posted and will show the issue.

      Thanks for looking into this.
      Last edited by ETFVoyageur; 08-04-2016, 10:35 AM.

      Comment


        #4
        Jesse,

        I just sent you an upgraded test case. The problem is that reflection fails if the expandable object constructor takes a parameter. It works fine if the expandable object constructor takes no arguments. The upgraded test case makes it easy to switch between the tests, showing failure or success.

        Comment


          #5
          Update / information:

          It turns out that is per design -- cannot serialize a class without a default constructor. Now that I have made that change the issue has changed. The system cannot generate the XML. It looks like the problem is that the class has a variable that is an abstract class -- it needs to store a pointer to an abstract base class that using indicators have in common. That is fine as long as it is not initialized, but fails when it is initialized. Still trying to figure out how to get by that one.

          Comment


            #6
            OK -- seems to be all working now. For general information there were two issues:

            1) The expandable object must have a default constructor

            2) The abstract base class pointer needs to be a property, with [Browsable(false)] and [XmlIgnore]

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by GussJ, 03-04-2020, 03:11 PM
            15 responses
            3,271 views
            0 likes
            Last Post xiinteractive  
            Started by Tim-c, Today, 02:10 PM
            1 response
            8 views
            0 likes
            Last Post NinjaTrader_ChelseaB  
            Started by Taddypole, Today, 02:47 PM
            0 responses
            2 views
            0 likes
            Last Post Taddypole  
            Started by chbruno, 04-24-2024, 04:10 PM
            4 responses
            51 views
            0 likes
            Last Post chbruno
            by chbruno
             
            Started by TraderG23, 12-08-2023, 07:56 AM
            10 responses
            403 views
            1 like
            Last Post beobast
            by beobast
             
            Working...
            X