Quantcast
Channel: Windows Forms General forum
Viewing all articles
Browse latest Browse all 12583

[C#] CollectionChanged issues with ObservableCollection

$
0
0

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.


Viewing all articles
Browse latest Browse all 12583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>