ComboBox.Items.Clear() not working -- Totally Revised Question
-
My last post about this issue resulted in a lot of confusion. So I want to try this a different way: I'm making a custom time picker that inherits directly from ComboBox. I am not using a designer to make a System.Windows.Forms.UserControl-based control. I will post the full code in a moment to clarify. The control has a property called Increment, which is the increment in minutes between each ComboBox item. Therefore the "set" action of Increment invokes the private method RepopulateChoices(). The method is also invoked in the "set" action of another property called ShowMilitary. The first line of RepopulateChoices() is:
Items.Clear();
Remember I'm inheriting directly from ComboBox, so this syntax is CORRECT. It does not need to be prefixed by "myComboBox1." or anything like that. It is not a designer-based user control. The problem is that I end up with duplicate items. Example: If I set Increment = 30, I'll see the items 11:00 PM, 11:30 PM, and then 12:00 AM, 12:30 AM and it keeps going. The number of duplicates depends on the nesting of containers, adding 2 days' worth of entries for every layer: Dropped directly on a form: 96 entries (2 days @ 30 minute increments) Dropped in a panel on a form: 192 entries (4 days) Dropped in a panel in a TableLayout cell on a form: 288 entries (6 days) It's like Items.Clear() is failing to do anything. I'm trying to figure out why. Here is my complete class code:using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;namespace PCA.SecureWinCtrls
{
[Description("Control for displaying a time selection combox box with custom time increments. Includes provision for PCA securiyt model."),
ToolboxBitmap(typeof(ComboBox))]
public sealed class pcaTimePicker : ComboBox
{
#region MEMBERS/// <summary> /// Override of the base ComboBox property. Style cannot be altered due to the specific /// use of this control. /// </summary> \[Browsable(false)\] public new ComboBoxStyle DropDownStyle { get { return ComboBoxStyle.DropDown; } } /// <summary> /// Gets the current hours value. If no value is set, and exception will be thrown. /// </summary> \[Browsable(false)\] public int Hours {
-
My last post about this issue resulted in a lot of confusion. So I want to try this a different way: I'm making a custom time picker that inherits directly from ComboBox. I am not using a designer to make a System.Windows.Forms.UserControl-based control. I will post the full code in a moment to clarify. The control has a property called Increment, which is the increment in minutes between each ComboBox item. Therefore the "set" action of Increment invokes the private method RepopulateChoices(). The method is also invoked in the "set" action of another property called ShowMilitary. The first line of RepopulateChoices() is:
Items.Clear();
Remember I'm inheriting directly from ComboBox, so this syntax is CORRECT. It does not need to be prefixed by "myComboBox1." or anything like that. It is not a designer-based user control. The problem is that I end up with duplicate items. Example: If I set Increment = 30, I'll see the items 11:00 PM, 11:30 PM, and then 12:00 AM, 12:30 AM and it keeps going. The number of duplicates depends on the nesting of containers, adding 2 days' worth of entries for every layer: Dropped directly on a form: 96 entries (2 days @ 30 minute increments) Dropped in a panel on a form: 192 entries (4 days) Dropped in a panel in a TableLayout cell on a form: 288 entries (6 days) It's like Items.Clear() is failing to do anything. I'm trying to figure out why. Here is my complete class code:using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;namespace PCA.SecureWinCtrls
{
[Description("Control for displaying a time selection combox box with custom time increments. Includes provision for PCA securiyt model."),
ToolboxBitmap(typeof(ComboBox))]
public sealed class pcaTimePicker : ComboBox
{
#region MEMBERS/// <summary> /// Override of the base ComboBox property. Style cannot be altered due to the specific /// use of this control. /// </summary> \[Browsable(false)\] public new ComboBoxStyle DropDownStyle { get { return ComboBoxStyle.DropDown; } } /// <summary> /// Gets the current hours value. If no value is set, and exception will be thrown. /// </summary> \[Browsable(false)\] public int Hours {
I should add that when I step-trace through RepopulateChoices() everything seems fine. When I exit the method and hit F5 to continue, my breakpoint is no longer encountered but I still end up with duplicate items. That's what is making this so darn frustrating.
-
My last post about this issue resulted in a lot of confusion. So I want to try this a different way: I'm making a custom time picker that inherits directly from ComboBox. I am not using a designer to make a System.Windows.Forms.UserControl-based control. I will post the full code in a moment to clarify. The control has a property called Increment, which is the increment in minutes between each ComboBox item. Therefore the "set" action of Increment invokes the private method RepopulateChoices(). The method is also invoked in the "set" action of another property called ShowMilitary. The first line of RepopulateChoices() is:
Items.Clear();
Remember I'm inheriting directly from ComboBox, so this syntax is CORRECT. It does not need to be prefixed by "myComboBox1." or anything like that. It is not a designer-based user control. The problem is that I end up with duplicate items. Example: If I set Increment = 30, I'll see the items 11:00 PM, 11:30 PM, and then 12:00 AM, 12:30 AM and it keeps going. The number of duplicates depends on the nesting of containers, adding 2 days' worth of entries for every layer: Dropped directly on a form: 96 entries (2 days @ 30 minute increments) Dropped in a panel on a form: 192 entries (4 days) Dropped in a panel in a TableLayout cell on a form: 288 entries (6 days) It's like Items.Clear() is failing to do anything. I'm trying to figure out why. Here is my complete class code:using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;namespace PCA.SecureWinCtrls
{
[Description("Control for displaying a time selection combox box with custom time increments. Includes provision for PCA securiyt model."),
ToolboxBitmap(typeof(ComboBox))]
public sealed class pcaTimePicker : ComboBox
{
#region MEMBERS/// <summary> /// Override of the base ComboBox property. Style cannot be altered due to the specific /// use of this control. /// </summary> \[Browsable(false)\] public new ComboBoxStyle DropDownStyle { get { return ComboBoxStyle.DropDown; } } /// <summary> /// Gets the current hours value. If no value is set, and exception will be thrown. /// </summary> \[Browsable(false)\] public int Hours {
I get your problem now. There's no way that the Items.Clear() doesn't work. The problem might be from drawing(paint event(s)). Ex: you drop your control on the form. The Ctor calls the RepopulateChoices. Then the paint event is raised and ads the items once again. Drop on a panel on a form. Form invalidate=> your control invalidate. Panel invalidate again => your control invalidates. That's the only reason that I could think of. But it might not be this at all. Do you override the OnPaint?
-
My last post about this issue resulted in a lot of confusion. So I want to try this a different way: I'm making a custom time picker that inherits directly from ComboBox. I am not using a designer to make a System.Windows.Forms.UserControl-based control. I will post the full code in a moment to clarify. The control has a property called Increment, which is the increment in minutes between each ComboBox item. Therefore the "set" action of Increment invokes the private method RepopulateChoices(). The method is also invoked in the "set" action of another property called ShowMilitary. The first line of RepopulateChoices() is:
Items.Clear();
Remember I'm inheriting directly from ComboBox, so this syntax is CORRECT. It does not need to be prefixed by "myComboBox1." or anything like that. It is not a designer-based user control. The problem is that I end up with duplicate items. Example: If I set Increment = 30, I'll see the items 11:00 PM, 11:30 PM, and then 12:00 AM, 12:30 AM and it keeps going. The number of duplicates depends on the nesting of containers, adding 2 days' worth of entries for every layer: Dropped directly on a form: 96 entries (2 days @ 30 minute increments) Dropped in a panel on a form: 192 entries (4 days) Dropped in a panel in a TableLayout cell on a form: 288 entries (6 days) It's like Items.Clear() is failing to do anything. I'm trying to figure out why. Here is my complete class code:using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;namespace PCA.SecureWinCtrls
{
[Description("Control for displaying a time selection combox box with custom time increments. Includes provision for PCA securiyt model."),
ToolboxBitmap(typeof(ComboBox))]
public sealed class pcaTimePicker : ComboBox
{
#region MEMBERS/// <summary> /// Override of the base ComboBox property. Style cannot be altered due to the specific /// use of this control. /// </summary> \[Browsable(false)\] public new ComboBoxStyle DropDownStyle { get { return ComboBoxStyle.DropDown; } } /// <summary> /// Gets the current hours value. If no value is set, and exception will be thrown. /// </summary> \[Browsable(false)\] public int Hours {
The problem are the static items in the Items property on design-time. Just go to your form design->select a pcaTimePicker->Properties->Items delete everything in it. After that you should not have any problems. The problem are the following lines in the designer-file:
this.pcaTimePicker3.FormattingEnabled = true; this.pcaTimePicker3.Items.AddRange(new object\[\] { "12:00 ", "12:30 ", "1:00 ", "1:30 ", "2:00 ", "2:30 ", ...}); this.pcaTimePicker3.Location = new System.Drawing.Point(101, 243); this.pcaTimePicker3.Name = "pcaTimePicker3"; this.pcaTimePicker3.Size = new System.Drawing.Size(121, 21); this.pcaTimePicker3.TabIndex = 5;
Those lines get called after your pcaTimePicker first invokes Repopulate(...). Here some example:
public Form1() { InitializeComponent(); MessageBox.Show(pcaTimePicker3.Items.Count.ToString()); // displays 96 pcaTimePicker3.Items.Clear(); // clear items the were added by designer pcaTimePicker3.Increment = 30; // inderect invoke of Repop... MessageBox.Show(pcaTimePicker3.Items.Count.ToString()); // displays correct value 48! }
Hope I could help you.
Greetings Covean
-
The problem are the static items in the Items property on design-time. Just go to your form design->select a pcaTimePicker->Properties->Items delete everything in it. After that you should not have any problems. The problem are the following lines in the designer-file:
this.pcaTimePicker3.FormattingEnabled = true; this.pcaTimePicker3.Items.AddRange(new object\[\] { "12:00 ", "12:30 ", "1:00 ", "1:30 ", "2:00 ", "2:30 ", ...}); this.pcaTimePicker3.Location = new System.Drawing.Point(101, 243); this.pcaTimePicker3.Name = "pcaTimePicker3"; this.pcaTimePicker3.Size = new System.Drawing.Size(121, 21); this.pcaTimePicker3.TabIndex = 5;
Those lines get called after your pcaTimePicker first invokes Repopulate(...). Here some example:
public Form1() { InitializeComponent(); MessageBox.Show(pcaTimePicker3.Items.Count.ToString()); // displays 96 pcaTimePicker3.Items.Clear(); // clear items the were added by designer pcaTimePicker3.Increment = 30; // inderect invoke of Repop... MessageBox.Show(pcaTimePicker3.Items.Count.ToString()); // displays correct value 48! }
Hope I could help you.
Greetings Covean
BRILLIANT, Covean!!! I never would have thought of looking at the designer file. That started me thinking that there has to be a way to prevent design-time population. At first I just tried adding a check against the ComboBox.DesignMode property. However, RepopulateChoices() is also called from the constructor, and DesignMode doesn't register that early. On the other hand, if I removed the call from the constructor, then nothing was populated at run-time. My final solution was: 1. Remove the call to RepopulateChoices() from the constructor. 2. Override the InitLayout method like this:
protected override void InitLayout() { base.InitLayout(); if (DesignMode) return; RepopulateChoices(); }
That prevents any items from being populated at design time and still populates the ComboBox at run-time with exactly ONE set of data. Thanks again.
-
BRILLIANT, Covean!!! I never would have thought of looking at the designer file. That started me thinking that there has to be a way to prevent design-time population. At first I just tried adding a check against the ComboBox.DesignMode property. However, RepopulateChoices() is also called from the constructor, and DesignMode doesn't register that early. On the other hand, if I removed the call from the constructor, then nothing was populated at run-time. My final solution was: 1. Remove the call to RepopulateChoices() from the constructor. 2. Override the InitLayout method like this:
protected override void InitLayout() { base.InitLayout(); if (DesignMode) return; RepopulateChoices(); }
That prevents any items from being populated at design time and still populates the ComboBox at run-time with exactly ONE set of data. Thanks again.
No problem. I also needed some time to find out whats wrong with it because of that very strange behaviour (hard question!). I also learned something new for me so 5 points for this question. :laugh: (And sorry for my cruel typos/english in my last post. I'm ashamed. :-O :laugh: )
Greetings Covean
-
No problem. I also needed some time to find out whats wrong with it because of that very strange behaviour (hard question!). I also learned something new for me so 5 points for this question. :laugh: (And sorry for my cruel typos/english in my last post. I'm ashamed. :-O :laugh: )
Greetings Covean
And 5 for the answer seeing as OP forgot!
Dave
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Why are you using VB6? Do you hate yourself? (Christian Graus) -
And 5 for the answer seeing as OP forgot!
Dave
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Why are you using VB6? Do you hate yourself? (Christian Graus)