Overriding EndInit on inherited Spread control

Posted by: brunosilva on 8 September 2017, 12:35 pm EST

  • Posted 8 September 2017, 12:35 pm EST


    I have a user control which inherits from farpoint.win.spread.fpspread.

    In previous version of spread I made appearence changes to the spread sheets when sheets where added to the spread, but now this changes aren't being reflected because of the routine sheet.reset being executed in the initializecomponent. I don't wan't my appearence changes to be serialized in the forms, so that when I make changes to my usercontrol they are immediatly reflected to the forms without having to design them again.

    I thought of overriding the EndInit routine of fpspread but it isn't ovverridable. Then I tried to implement it, but I don't know how to call the mybase.Endinit.

    Overriding this routine I could execute code after the initializecomponent of the parent form.

    Here's my custom control code (which can't be compiled...):

    <FONT color=#0000ff size=2><FONT color=#0000ff size=2>

    Public</FONT><FONT color=#000000 size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT color=#000000 size=2> EndInit() </FONT><FONT color=#0000ff size=2>Implements</FONT><FONT size=2><FONT color=#000000> ISupportInitialize.EndInit</FONT>

    </FONT><FONT color=#0000ff size=2>   CType</FONT><FONT size=2>(</FONT><FONT color=#0000ff size=2>MyBase</FONT><FONT size=2>, System.ComponentModel.ISupportInitialize).EndInit()


    </FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub

    </FONT></FONT><FONT color=#000000>How can I execute code after the parent form finishes the initializecomponent?</FONT>


    Thanks in advance.


  • Replied 8 September 2017, 12:35 pm EST

    I cannot tell what exactly you are doing or trying to do from your description.

    Do you have a class which inherits from FarPoint.Win.Spread.FpSpread or from System.Windows.Forms.UserControl?  Are you trying to make a subclassed FpSpread that looks a certain way, or are you making a user control that contains a Spread and makes it look a certain way?  The way that the design time serialization works for those two cases is very different.

    UserControl works much like a form does, and creates its own InitializeComponent code to initialize its contents.  Spread will serialize itself to the code the same as it does when it is put into a form, and the code will be regenerated whenever you make changes to the contents of the user control at design time with Visual Studio, just as with a form.  Creating a public API for developers to use your user control requires you to implement everything that you want exposed to the developer (since the FpSpread is embedded and not subclassed), and the design time code serialization is based entirely on your user control's public API, and is unrelated to the FpSpread's API.  You can implement ISupportInitialize on your user control and the form will create code to call into your BeginInit and EndInit methods to inform your control that initialization is beginning or ending.  Adding an implementation of that interface is all you should need to do to get your code called after the form's InitializeComponent code is finished.

    Creating a class which inherits directly from FpSpread is quite different, and trying to make a subclassed control for use at design time is not recommended.  Subclassed controls are good solutions for extending the Spread's public interface with new run-time functionality, but trying to extend its design time functionality is much harder because most of the classes that Spread uses for design time support are not public.  You would need to basically reimplement anything you wanted to override or change in the design time support for the control.  Adding new design time support for new functionality you are adding to the FpSpread's public API is not very difficult though; for example, you could inherit from FpSpread and extend the control with a new property that has attributes like CategoryAttribute and DesignerSerializationVisibilityAttribute and TypeConverterAttribute or EditorAttribute, and the inherited control would show your new property in the property grid and use your type converter or editor to edit its value.  But adding a new verb for your own custom cells editor would be more difficult, since the ControlDesigner class for Spread is not public.  You could not subclass it directly, and you would have to use reflection to create an instance of it if you wanted to delegate some calls into our designer class.

    Overriding the ISupportInitialize methods in FpSpread is not possible as you have noted, since the methods are not virtual.  You can replace the implementation and delegate calls to the base class methods, but Visual Basic does not make this very convenient as you have noted.  It is easier to do in C# code, but it can be done in VB code too using reflection:

    Public Sub BeginInit Implements ISupportInitialize.BeginInit
    GetType(FarPoint.Win.Spread.FpSpread).GetInterfaceMap(GetType(System.ComponentModel.ISupportInitialize)).TargetMethods(0).Invoke(Me, System.Reflection.BindingFlags.InvokeMethod, Nothing, Nothing, Nothing)
    End Sub

    Public Sub EndInit Implements ISupportInitialize.EndInit
    GetType(FarPoint.Win.Spread.FpSpread).GetInterfaceMap(GetType(System.ComponentModel.ISupportInitialize)).TargetMethods(1).Invoke(Me, System.Reflection.BindingFlags.InvokeMethod, Nothing, Nothing, Nothing)
    End Sub
  • Replied 8 September 2017, 12:35 pm EST

    Many thanks for your answer.

    In my case, i have a class which inherits from fpspread, and any design change I want, I make it in runtime.

    Your delegate calls to the base class worked like a charm...

    Once again, many thanks..

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels