3

I have a WinForm-UserControl with a generic type for a control. To create the instance, I changed the Designer code:

public class TimeBarForm<T> : where T : TimeBarPanel
{
    protected void InitializeComponent()
    {
        // ...
        this.m_timeBarPanel = (T)Activator.CreateInstance(typeof(T));
        // ...
    }
}

This works fine at compile time but on design time it's broken. On the TimeBarForm:

Failed to parse method 'InitializeComponent'. The parser reported the following error 
'Type parameters are not suppported Parameter name: typeSymbol'. 
Please look in the Task List for potential errors.

The derived classes just show the default designer for an empty user control.

I also tried to pass the type in the constructor but VS complains that I should not touch autogenerated code (It dosn't like the if-conditions). I want a generic UserControl where I can decide about the specialization of an abstract class/control in a derived type and I should still be able to use the designer in the base class. I'm open to other suggestions to solve this as this might not be the best solution. I'm not very used to UserControl-design.

VS 2015/ .Net 4.6

Peter Schneider
  • 1,683
  • 12
  • 31
  • As a general rule, don't change designer generated codes by hand. It may break the designer or your codes may be removed if the designer change. The designer works based in parsing and deserializing. As described in the error, it couldn't deserialize the code. Take a look at this post [Can't view designer when coding a form in C#](http://stackoverflow.com/a/32299687/3110834). It contains useful information about how the designer works. Also it contains an interesting example which helps you to understand how the designer works. – Reza Aghaei Jul 21 '16 at 19:07
  • It it possible for you to make your base control `TimeBarPanel` non-abstract (because of designer purpose)? – Reza Aghaei Jul 21 '16 at 19:24
  • It is non-abstract in my current implementation. But I have to "inject" the specialization somehow. – Peter Schneider Jul 21 '16 at 19:27

1 Answers1

1

I've done a somewhat dirty workaround but I can use the designer for the base and derived classes. I removed the generic and replaced the Activator-class with a call to the constructor. When I'm done with designing the base class I coment this line. The derived classes call the constructor to pass the instance:

    public TimeBarForm(TimeBarPanel timeBarPanel)
    {
        this.m_timeBarPanel = timeBarPanel;
        InitializeComponent();
    }

To make the designer for the derived classes happy, a second constructor provides a default instance:

    public TimeBarForm()
    {
        this.m_timeBarPanel = new TimeBarPanel();
        InitializeComponent();
    }

Not pretty but I can live with it.

Peter Schneider
  • 1,683
  • 12
  • 31