locked
Strange Problems Extending Combobox RRS feed

  • Question

  • In a project one of my developers needed to reuse the same combobox in several places.

    The combobox would always have the same objects bound to it, and we wanted a few functions extra functions on the combobox that would centralize some functionality.

     

    So we inherit from combobox, and in the constructor of our class we create the 5 objects that we need in the dropdown and we add them to the combobox items collection.

     

    Everything works like it should.

     

    But we find that when we make a change in the designer for a form that uses this combobox, the designer puts stuff in the designer.vb file, that is trying to add items to our combobox.

    It uses the .items.AddRange(...) function and tries to add 1 item for every item that we add in the contructor.

     

    It's like it thinks it needs to remember these items that we programmatically add in the constructor.

     

    This code then blows up in the designer as well as when being executed.

     

    Does anyone know why the designer would try to autogenerate this type of code?

     

    I didn't find another event that we could use to add the items we need for the control.  It seems like the contructor is the only one (there is no OnActivated or anything like that).

     

    Anyone have any suggestions?

    Wednesday, August 27, 2008 10:03 PM

Answers

  • The Windows Forms designer executes the constructor of your control in design mode.  It therefore sees the items you added and thinks they were added by the user clicking the Items property in the Properties window.  And thus generates the code to create those items at runtime.  You'll get the items twice.

    Not so sure if the previous poster's workaround will work.  Here's another one:

    using System;
    using System.Windows.Forms;

    public class MyComboBox : ComboBox {
      protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        // Add standard items at runtime
        if (!this.DesignMode && this.Items.Count == 0) {
          this.Items.AddRange(new object[] { "one", "two", "three" });
        }
      }
    }
    Saturday, August 30, 2008 7:34 PM
  • Ok here is the solution I found. I appreciate the suggested solutions that were already posted, but they didn't quite work for us, but they did get us looking in the right direction.

     

    Basically it came down to 2 problems:

    1) testing for .DesignMode has to be done on all controls up the chain, not just on the current control, and more importantly,2) testing for .DesignMode is useless in the constructor.

     

    So we used some functions to walk up the control hierarchy to test for DesignMode and we used another event to do out population rather than in the constructor. I put the code here if anyone wants it: http://chrismay.org/2008/10/08/Problems+Extending+Winforms+Combobox.aspx

    Wednesday, October 8, 2008 7:05 PM

All replies

  • hi

    first hide items property.

    then use this attribute for it :

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

    see sample :


    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

    public new ObjectCollection Items {
      get { return base.Items; }
    }


    Thursday, August 28, 2008 4:42 AM
  • The Windows Forms designer executes the constructor of your control in design mode.  It therefore sees the items you added and thinks they were added by the user clicking the Items property in the Properties window.  And thus generates the code to create those items at runtime.  You'll get the items twice.

    Not so sure if the previous poster's workaround will work.  Here's another one:

    using System;
    using System.Windows.Forms;

    public class MyComboBox : ComboBox {
      protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        // Add standard items at runtime
        if (!this.DesignMode && this.Items.Count == 0) {
          this.Items.AddRange(new object[] { "one", "two", "three" });
        }
      }
    }
    Saturday, August 30, 2008 7:34 PM
  • Ok here is the solution I found. I appreciate the suggested solutions that were already posted, but they didn't quite work for us, but they did get us looking in the right direction.

     

    Basically it came down to 2 problems:

    1) testing for .DesignMode has to be done on all controls up the chain, not just on the current control, and more importantly,2) testing for .DesignMode is useless in the constructor.

     

    So we used some functions to walk up the control hierarchy to test for DesignMode and we used another event to do out population rather than in the constructor. I put the code here if anyone wants it: http://chrismay.org/2008/10/08/Problems+Extending+Winforms+Combobox.aspx

    Wednesday, October 8, 2008 7:05 PM