Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Monday, July 7, 2008 7:54 PM
Hello,
I would like to know, if the ListBox have any event when adding or removing Items?
The background is the following:
I have in a form two listboxes with "<", "<<", ">>"and ">" buttons.
When clicking on it I add or remove items like:
| private void Exchange(int srcIndex, ListBox src, ListBox dest) |
| { |
| if (srcIndex >= 0) |
| { |
| object item = src.Items[srcIndex]; |
| if (null != item) |
| { |
| dest.Items.Add(item); |
| src.Items.Remove(item); |
| } |
| } |
| } |
I would like to change a local boolean "isListModified" in true, when a adding or removing in (one of) the lists are made.
Best regards, Sergiu
All replies (8)
Thursday, July 10, 2008 10:31 AM ✅Answered
Hi Sergiu,
As far as I know, Listbox has no built-in mechanism to process item add/delete event.
Anyway, perhaps you can try to bind a data source to the listbox control, and then you can add/delete the items of the listbox by modify the data source, definitely, you can define you own custom event to process item add/delete event in the data source.
In addition to this, please refer to the following LINKs.
http://msdn.microsoft.com/en-us/library/system.windows.forms.listcontrol.datasource.aspx
MSDN: Events (C# Programming Guide)
CodeProject: Creating advanced C# custom events
Regards,
Xun
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Thursday, July 10, 2008 1:07 PM ✅Answered
Hi Sergio!
I agree with you, sometimes it would be nice to have those events. It's not just the ListBox that is missing notification when items are being added or removed. Normally you would have some data store behind the lists that can take care of this for you but wouldn't it be great to have the events anyway.
I made a wrapper for the ListBox control that provides a new interface for adding and removing items. This way I can fire events when I need to, and since this is all encapsulated in the ListBox wrapper I won't need to think of all the places where someone or something may change the inner collection. Isn't that why we have the events !?
Here's the code: (...and if you haven't used self-made components before you just have to add a new class to your project, paste the code and compile. The new version of the ListBox can now be found in the ToolBox when you swith to designing your form)
| public class ListBoxItemEventArgs : EventArgs |
| { |
| private int index; |
| public ListBoxItemEventArgs(int index) |
| { |
| this.index = index; |
| } |
| public int Index |
| { |
| get |
| { |
| return this.index; |
| } |
| } |
| } |
| /// <summary> |
| /// Represents a ListBox with events for when adding and removing items. |
| /// In order for this to work the AddItem, RemoveItem, InsertItem and ClearItems methods |
| /// of this class must be used rather than accessing the Items collection it self. |
| /// </summary> |
| public class ListBoxWithEvents : ListBox |
| { |
| public event EventHandler<ListBoxItemEventArgs> ItemAdded; |
| public event EventHandler<ListBoxItemEventArgs> ItemRemoved; |
| public new ListBox.ObjectCollection Items |
| { |
| get |
| { |
| throw (new InvalidOperationException( |
| "Use the built in methods instead for manipulating the collection directly")); |
| } |
| } |
| public void AddItemRange(object[] items) |
| { |
| foreach (object item in items) |
| this.AddItem(item); |
| } |
| public void AddItem(object item) |
| { |
| this.InsertItem(base.Items.Count, item); |
| } |
| public void InsertItem(int index, object item) |
| { |
| base.Items.Insert(index, item); |
| this.OnItemAdded(index); |
| } |
| public void RemoveItem(object item) |
| { |
| int index = base.Items.IndexOf(item); |
| if (index > -1) |
| this.RemoveItemAt(index); |
| } |
| public void ClearItems() |
| { |
| for (int i = base.Items.Count - 1; i >= 0; i--) |
| this.RemoveItemAt(i); |
| } |
| public void RemoveItemAt(int index) |
| { |
| base.Items.RemoveAt(index); |
| this.OnItemRemoved(index); |
| } |
| protected virtual void OnItemAdded(int index) |
| { |
| if (this.ItemAdded != null) |
| this.ItemAdded(this, new ListBoxItemEventArgs(index)); |
| } |
| protected virtual void OnItemRemoved(int index) |
| { |
| if (this.ItemRemoved != null) |
| this.ItemRemoved(this, new ListBoxItemEventArgs(index)); |
| } |
| } |
/Calle
Monday, July 7, 2008 7:56 PM
Why don't you just set it when Exchange runs? I don't know of any events on add/remove.
Monday, July 7, 2008 8:00 PM
well, exchange is a static function. I use it in many forms.
But the local boolean should be modified in a lot of places.. "AddClick" "RemoveClick", "AddAllClick", "RemoveAllClick"...
Best regards, Sergiu
Thursday, July 10, 2008 1:54 PM
here is what you can do:
| public partial class YourForm : Form |
| { |
| public event EventHandler YourEvent; |
| public YourForm() |
| { |
| InitializeComponent(); |
| YourEvent += YourEventHandler; |
| } |
| private void YourEventHandler(object sender, EventArgs e) |
| { |
| MessageBox.Show("Item has been added."); |
| } |
| private void YourButton_Click(object sender, EventArgs e) |
| { |
| YourListBox.Items.Add("Item..."); |
| YourEvent(this, new EventArgs()); |
| } |
| } |
the example above does the following:
- creates event
- creates method that will be called when event is fired
- adds that method to the event
- after item is added to listbox - event is called - this starts the method which was added to the event
Sunday, July 13, 2008 4:17 PM | 2 votes
I posted an article on CodeProject that describes another solution to this issue than in my previous post.
/Calle
Wednesday, June 11, 2014 2:52 PM
/// <summary>
/// Represents a ListBox with events for when adding and removing items.
/// </summary>
public class ListBoxWithEvents : ListBox
{
public event EventHandler<ListBoxItemEventArgs> ItemAdded;
public event EventHandler<ListBoxItemEventArgs> ItemRemoved;
public ListBoxWithEvents() : base()
{
((INotifyCollectionChanged)Items).CollectionChanged += HandleCollectionChanged;
}
private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems == null && e.OldItems == null)
{
// seems we got a new collection
foreach (var x in Items)
{
OnItemAdded(Items.IndexOf(x));
}
}
if (e.NewItems != null)
{
foreach (var x in e.NewItems)
{
OnItemAdded(Items.IndexOf(x));
}
}
if (e.OldItems != null)
{
foreach (var x in e.OldItems)
{
OnItemRemoved(Items.IndexOf(x));
}
}
if (e.Action == NotifyCollectionChangedAction.Move)
{
//do something
}
}
protected virtual void OnItemAdded(int index)
{
if (ItemAdded != null)
{
ItemAdded(this, new ListBoxItemEventArgs(index));
}
}
protected virtual void OnItemRemoved(int index)
{
if (ItemRemoved != null)
{
ItemRemoved(this, new ListBoxItemEventArgs(index));
}
}
}
public class ListBoxItemEventArgs : EventArgs
{
public ListBoxItemEventArgs(int index)
{
Index = index;
}
public int Index { get; private set; }
}
Friday, October 27, 2017 3:06 PM
Hi andre_fiedler
This code doesn't work because Items is not an INotifyCollectionChanged type.
Listbox Items is only ICollection, IEnumerable and IList.