Hello, I'm developing a Windows Form Control which is indeed a ListBox. My idea is that if you created a new ObservableCollection then it will .Clear() the existing one inside the ListBox class. This works fine, but when I am using CollectionChanged and trying to remove ALL labels off of the form - it doesn't.
What's suppose to happen is that the first ObservableCollection is created using two values, and then a second ObservableCollection is created using one value. When the latter is created, it is suppose to remove all elements in the ObservableCollection inside the ListBox class. As stated, that works - but when the CollectionChanged event is thrown, I call RemoveAllItems which is suppose to loop through all labels and remove them.
Remember when I said only two values are there at first? It detects 2 controls inside the control itself - that should be good, right? Well, it removes only ONE. Then of course the value on the latter ObservableCollection created is then added so you end up with 2 items in the ListBox - nuh'h! Should be only one.
Here is the Form in which I am using the ListBox control on.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Collections.ObjectModel; namespace ControlTesting { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.flexibleListBox1.ItemCollection = new ObservableCollection<string>() {"foo", "hello" }; this.flexibleListBox1.ItemCollection = new ObservableCollection<string>() {"bar" }; } private void flexibleListBox1_itemDoubleClicked(Label Sender) { MessageBox.Show(this.flexibleListBox1.getSelectedItem().Text); } } }
Here is the relevant part to the ListBox class
using System; using System.Collections.Specialized; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing; using System.ComponentModel; using System.Globalization; namespace FlexibleListBox { public class FlexibleListBox : UserControl { private ObservableCollection<String> itemCollection = new ObservableCollection<String>(); public ObservableCollection<String> ItemCollection { get { return this.itemCollection; } set { this.itemCollection.Clear(); foreach (string v in value) { this.itemCollection.Add(v); } } } public FlexibleListBox() { this.AutoScroll = true; this.itemCollection.CollectionChanged += this.itemCollectionChanged; } private void itemCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case System.Collections.Specialized.NotifyCollectionChangedAction.Add: if (e.NewItems != null) { foreach (string item in e.NewItems) { this.addItem(item); } } break; case System.Collections.Specialized.NotifyCollectionChangedAction.Reset: this.removeAllItems(); break; default: break; } } private void addItem(string text) { Label label = new Label(); label.Visible = false; label.Tag = label.Text = text; label.TextAlign = ContentAlignment.MiddleLeft; this.Controls.Add(label); label.MouseEnter += this.item_MouseEnter; label.MouseLeave += this.item_MouseLeave; label.MouseClick += this.item_MouseClick; label.MouseDoubleClick += this.item_MouseDoubleClick; this.Invalidate(); } private void removeAllItems() { foreach (Label label in this.Controls) { this.Controls.Remove(label); } } } }
In case the above doesn't give you enough information of what's happening, here is the entire ListBox class.
using System; using System.Collections.Specialized; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing; using System.ComponentModel; using System.Globalization; namespace FlexibleListBox { public class FlexibleListBox : UserControl { public delegate void itemDoubleClickedDelegate(Label Sender); public event itemDoubleClickedDelegate itemDoubleClicked; private int x = 0, y = 0; private Color itemBackColor = Color.White; private Color itemForeColor = Color.Black; private Color itemHoverBackColor = SystemColors.Control; private Color itemHoverForeColor = Color.Black; private Color itemActiveBackColor = Color.FromArgb(0, 149, 204); private Color itemActiveForeColor = Color.White; private int itemHeight = 10; private Padding itemPadding = new Padding(0); private Label activeItem; private ObservableCollection<String> itemCollection = new ObservableCollection<String>(); public Color ItemBackColor { get { return this.itemBackColor; } set { this.itemBackColor = value; this.Invalidate(); } } public Color ItemForeColor { get { return this.itemForeColor; } set { this.itemForeColor = value; this.Invalidate(); } } public Color ItemHoverBackColor { get { return this.itemHoverBackColor; } set { this.itemHoverBackColor = value; this.Invalidate(); } } public Color ItemHoverForeColor { get { return this.itemHoverForeColor; } set { this.itemHoverForeColor = value; this.Invalidate(); } } public Color ItemActiveBackColor { get { return this.itemActiveBackColor; } set { this.itemActiveBackColor = value; this.Invalidate(); } } public Color ItemActiveForeColor { get { return this.itemActiveForeColor; } set { this.itemActiveForeColor = value; this.Invalidate(); } } public int ItemHeight { get { return this.itemHeight; } set { this.itemHeight = value; this.Invalidate(); } } public Padding ItemPadding { get { return this.itemPadding; } set { this.itemPadding = value; this.Invalidate(); } } public ObservableCollection<String> ItemCollection { get { return this.itemCollection; } set { this.itemCollection.Clear(); foreach (string v in value) { this.itemCollection.Add(v); } } } public FlexibleListBox() { this.AutoScroll = true; this.itemCollection.CollectionChanged += this.itemCollectionChanged; foreach (string item in this.itemCollection) { this.addItem(item); } } public Label getSelectedItem() { return this.activeItem; } private void item_MouseEnter(object sender, EventArgs e) { if ((Label)sender != this.activeItem) { ((Label)sender).BackColor = (this.itemHoverBackColor); ((Label)sender).ForeColor = (this.itemHoverForeColor); } } private void item_MouseLeave(object sender, EventArgs e) { if ((Label)sender != this.activeItem) { ((Label)sender).BackColor = (this.itemBackColor); ((Label)sender).ForeColor = (this.itemForeColor); } } private void item_MouseClick(object sender, MouseEventArgs e) { switch (e.Button) { case MouseButtons.Left: foreach (Label label in this.Controls) { label.BackColor = (this.itemBackColor); label.ForeColor = (this.itemForeColor); } this.activeItem = (Label)sender; this.activeItem.BackColor = (this.itemActiveBackColor); this.activeItem.ForeColor = (this.itemActiveForeColor); break; } } private void item_MouseDoubleClick(object sender, MouseEventArgs e) { switch (e.Button) { case MouseButtons.Left: this.itemDoubleClicked((Label)sender); break; } } private void itemCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case System.Collections.Specialized.NotifyCollectionChangedAction.Add: if (e.NewItems != null) { foreach (string item in e.NewItems) { this.addItem(item); } } break; case System.Collections.Specialized.NotifyCollectionChangedAction.Remove: if (e.OldItems != null) { foreach (string item in e.OldItems) { this.removeItem(item); } } break; case System.Collections.Specialized.NotifyCollectionChangedAction.Reset: this.removeAllItems(); break; default: break; } } private void addItem(string text) { Label label = new Label(); label.Visible = false; label.Tag = label.Text = text; label.TextAlign = ContentAlignment.MiddleLeft; this.Controls.Add(label); label.MouseEnter += this.item_MouseEnter; label.MouseLeave += this.item_MouseLeave; label.MouseClick += this.item_MouseClick; label.MouseDoubleClick += this.item_MouseDoubleClick; this.Invalidate(); } private void removeItem(string text) { foreach (Label label in this.Controls) { if (label.Text == text) { this.Controls.Remove(label); break; } } } private void removeAllItems() { foreach (Control label in this.Controls) { if (label is Label) { this.Controls.Remove(label); } } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); this.y = 0; foreach (Label label in this.Controls) { label.BackColor = (this.itemBackColor); label.ForeColor = (this.itemForeColor); label.Width = this.Width; label.Padding = this.itemPadding; label.Height = this.itemHeight + (this.itemPadding.Top + this.itemPadding.Bottom); label.Location = new Point(x, y); label.Visible = true; this.y += label.Height; } if (this.VerticalScroll.Visible) { foreach (Label l in this.Controls) { l.Width = this.Width - SystemInformation.VerticalScrollBarWidth; } } } } }
Are you able to help me? As a quick summary, in the form that uses the ListBox I create two ObservableCollections, the first with 2 values the second with only 1 value. The output on the ListBox is "Hello" and "Bar" when it should be just "Bar"... it isn't removing my labels properly - but it is removing from the ObservableCollection defined in the ListBox class.