0

I realize there have been similar questions asked here before, but after scouring the site I've not found anything that addresses the specific issue I'm experiencing. I'm using C# in VS 2017. I have a base form and am trying to create/use an inherited form. The base form (frmDataEntry) contains several controls (a ListView, a ComboBox, two Labels, four Buttons, and a Panel. The inheriting form (frmEditRanch) adds six controls to the panel: three Labels, two Textboxes, and a PictureBox.

All of these controls appear and function as expected, except for the labels inside of the panel. Labels outside the panel are fine, as are the Textboxes and picturebox inside it; but the Label controls inside the panel do not show up. I'm stumped.

I've seen in other posts that the child form needs to create the controls in code, so I've tried that as well (creating the labels and adding them to the panel in code), but the result is no different.

Not sure how much code is needed to be helpful, but here is the initialization code that may be of some use.

BASE FORM:

public enum FormState { Idle, Adding, Editing }

public partial class frmDataEntry : Form
{
    protected AgData db = new AgData();
    protected Ranch ranch;
    public const int vScrollBarWidth = 21;

    public frmDataEntry()
    {
        InitializeComponent();
    }

    public frmDataEntry(int RanchID) : this()
    {
        ranch = db.GetRanch(RanchID);
    }

    protected void frmDataEntry_Load(object sender, EventArgs e)
    {
        if (DesignMode) return;
        UpdateRanchNameComboBox();
        cbRanchName.SelectedItem = ranch?.Name;
        ResetDataFields();
        SetFormControls(FormState.Idle);
        CreateListViewHeaders();
        UpdateRecordList();
    }
 ...

CHILD FORM:

public partial class frmEditRanch : frmDataEntry
{
    EditMode mode;

    public frmEditRanch(EditMode editMode, int RanchID = 0) : base(RanchID)
    {
        InitializeComponent();
        mode = editMode;
    }

    private void frmEditRanch_Load(object sender, EventArgs e)
    {
        AddDataControls();
    }

    protected override void AddDataControls()
    {
        Label lblName = new Label();
        lblName.Font = new Font(this.Font.FontFamily, 12, FontStyle.Regular);
        lblName.Text = "Name";
        lblName.TextAlign = ContentAlignment.MiddleLeft;
        lblName.AutoSize = false;
        lblName.Size = new Size(45, 20);
        lblName.Location = new Point(10, 23);
        pnlDataControls.Controls.Add(lblName);

        ...

        pnlDataControls.Refresh();

    }

 ...
Theo.Doc
  • 1
  • 1
  • BTW... _[Why should form inheritance be avoided?](https://softwareengineering.stackexchange.com/questions/191701/why-should-form-inheritance-be-avoided)_ –  Jun 26 '19 at 04:27
  • I use Form Inheritance in almost all my projects. Only in VS this has problems, and that is because of the idiot way the designer is build. Anyway, there is no need to create controls in code. If you put a panel on your ancestor, and on that panel you put a label (using the designer), both should show up on every child form. If not then maybe you have some code that tries to manage controls ? – GuidoG Jun 26 '19 at 06:07
  • What does the debugger tell you? Can you find the labels? Are they in the panel's controls collection? Do they have a suitable position? Text? – TaW Jun 26 '19 at 07:46
  • Override `OnLayout` in the base Form and perform the layout logic of the baseForm Controls there, using `this` as the reference Form (`this` will be your `frmEditRanch` Form at this time - well, any Form which inherits from the base Form). This way, all measures will be related to the inheriting Form, not the Base Form. You should also override `OnLoad`: better not to subscribe to events in the base Form. Your Forms should also always have an empty constructor; it won't cause harm here (in this specific code), but you should anyway. – Jimi Jun 26 '19 at 10:10
  • Yes that's a good point @Jimi The designer of VS needs the default ctor in order to work properly, even if in actual coding it is not needed – GuidoG Jun 26 '19 at 11:22
  • Thank you all for the replies. I do not have any code that tries to manage controls, so far as I know. As for the debugger - this is odd: when I add a label to the panel on the child form via the designer, even though I give it a text, the debugger shows a text value of "" (autosize=true; width=0) at runtime. If I assign the text to the label in code, the debugger reports it accurately, but either way the label still does not show up. I will try the suggestion of overriding the methods in the base form and update this post. – Theo.Doc Jun 26 '19 at 11:28
  • Jimi: perhaps I'm not doing something right, but when I add the default ctor to the child form (frmEditRanch), and run the project, the child form shows up with the panel from the base form rather than the panel (as altered) from the child form. – Theo.Doc Jun 26 '19 at 11:35
  • Jimi - I'm not sure I understand your suggestions for overriding methods. Are you saying I should put the "protected override void OnLayout(LayoutEventArgs levent)" procedure in the base form, and use it to create and configure all the controls that are on the base form via code? Or are you saying that I should put that method in the child form, overriding in that child form the base form's OnLayout method, and use that method to create and configure the additional controls that are specific to the child form? Thank you. – Theo.Doc Jun 26 '19 at 12:20
  • About the default constructor, you just need to add one and let it cascade-call any other contructor you need. In your case, could be `public frmEditRanch() : this(0) { }`. Override `OnLayout` of the base Form: when you reach this point, all measures and relative positions will refer to the Form that inherits from base Form, so you can reposition your controls using the inheriting Form's measures. Say, you want to position a control in the middle of the inhering Form: if you do this in the base Constructor, you'ld position the control in the middle of the base Form, not the inheriting one – Jimi Jun 26 '19 at 13:04
  • Overriding the OnLayout method and setting a control's location there, you'll position it in the middle of the inhering Form, which can have quite a different ClientArea than the base Form. See also the notes here: [How to get the size of an inherited form in the base form?](https://stackoverflow.com/a/55760332/7444103) – Jimi Jun 26 '19 at 13:04
  • The notes on the definition of the base Form inheritance in this example could also be useful: [How can I draw a rounded rectangle as the border for a rounded Form?](https://stackoverflow.com/a/56533229/7444103) – Jimi Jun 26 '19 at 13:15
  • UPDATE: Thanks to Jimi and all others who rallied to my aid on this perplexing issue. Here is what it took to finally get it to work: 1. First, it was important to instantiate the Label controls on the class level (not in any method); 2. Then, as Jimi suggested, I overrode the OnLayout method in my child form, and in this method set the properties of the labels, then added them to the panel control. I still have *no idea* why it is only Label controls that have this issue, and only when added to a container (panel) control. Everything else worked fine through the designer. – Theo.Doc Jun 26 '19 at 18:14

0 Answers0